[squeak-dev] The Trunk: Compiler-eem.480.mcz

Kjell Godo squeaklist at gmail.com
Sat Nov 26 20:01:38 UTC 2022


if you could dump obj1 or ( Error something )<—-[ you create it and fill it
but you do not signal it you just return it ] or some notNil into the data
pathway which could be tested at some one single place or a few places like
if the pathway was like a channel in a water shed with all the channels
coming together in a river at the sea and then you check for isError or
something at the mouth of the river like More and Just in Haskell but way
more expressive than More and Just then you know exactly what went wrong
and where maybe and that could be good maybe better than signal in this
case if there would be a lot of signals deprecated and a lot of on:do:s all
gone into one testing at the river ending

if you put all your UndefinedObject>>methods into a Category named by the
name of your Package or Project that should be ok it’s easy to hide it all
then. Like Category KEGGenerator in UndefinedObject hey that’s a good idea
i will do that
nil is an empty KEGGenerator and that is convenient but if nil is an empty
Collection also then is nil a Gen or a Coll so then you better use #(
 )asGen instead if that is a problem or maybe it’s fine sometimes it is
fine sometimes it is not
Object>>asGen ^self asGenerator

if KEGGenerator g and g next isNil then any g next later isNil also until (
g reset ).
This is essential to KEGGenerator if not the whole thing quits. But i use
KEGFooArray as a not nil end of something also. Probably KEGFooArray could
get a way better name because i just named it with out thinking and it
stuck. i guess i could use KEGGeneratorTail or something instead of nil but
nil is central and has a lot of testers which would have to be
isomorphically recreated slow so just use nil

I guess i could just rename KEGFooArray and the refactoring would change it
everywhere in one single stroke so probably i should do this try this but
what name should i choose and then the #fooArray local variables would look
funny so but what could it be called instead of KEGFooArray that means nil
like terminator Array in case you want to stick things into it like you do
with Errors but without creating another Error Class or something
KEGnotNilTerminator ? although KEGFooArray can be used for more than just
terminating sequences and once you know it it sticks in your craw in your
brain and you never forget it at least i never did so but KEGFooArray has a
nil like quality to it. i could look at all the KEGFooArray references and
see if it is mostly a not nil subsequence terminator

does anybody want KEGGenerator besides me i remember telling a co worker
you should use Generators by Timothy Budd for that and he said i don’t want
to use Generators for anything i just want to use to:do: to:by:do: do:
collect: select: reject: and detect: ok? Generators away. So i am guessing
that this is the general censure. the general opinion. Actually Generators
don’t do to:do: and to:by:do: as far as i know yet but some could do.
Otherwise they are similar to Collections and you can do aCollection asGen
or anObject asGen or aStream asGen etc. they are between Collections and
Streams so you do not have a lot of intermediate Collections created when
you do
((((( aCollection asGen
    ) collect: […]
    ) select: […]
    ) reject: […]
    ) detect: […] ifNone: […]
    ) ifNotNil: [ :g | g asArray ]
there are no intermediate Collections created none and asArray sends ( g
next ) over and over so execution proceeds
g next
     collect: select: reject: reject: detect:ifNone: etc
g next
     collect: select: reject: detect:ifNone: etc etc etc
sort of
and there is a new semaphore SharedQueue thing which does the java
     or something version of Generators from inside of regular loops
whileTrue:
and so you can have the […] above communicating with each other in very
convenient ways which come up a lot once you know to look and this highly
collapses the code as versus the Collection way is my opinion. But
KEGGenerators has got as big or bigger than Xtreams i believe i know
nothing and the combination of KEGGenerators and Xtreams aught to be pretty
good although i haven’t tried it yet pretty good i would think but nobody
wants it and nobody is me just me alone apparently

i use it a lot just like LittleSmalltalk uses its predecessor Generator a
lot
also look at the Icon language book and the implementation of n Queens
therein it’s like one line or something because everything in Icon is a
Generator practically or something

oh god        another thing to learn   by spelunking         no

well actually KEGGenerators is highly documented by Package comments Class
comments and Method comments completely Not corporate or consistent. well
it may be consistent mostly but not wholly and it’s definitely not
corporate or the ancient IBM standard accounting to which i say : what me
worry?

oh god        another huge pile up of pages to read         yes

and the older comments are highly convoluted i have found unfortunately but
the newer ones are pretty good clear i am hoping well future me is hoping

i want to put the latest versions of KEGGenerators into Github but it is
rather large with many optional addon Packages and there are many
Experimental Methods as well which could be Categorized KEGExperimental and
or KEGUnfinished and it’s Dolphin so there are Methods in multiple
Categories. So i was going to try to break it up into more Packages so you
just get what you want like a Core and some addons or something or should i
just dump the whole thing now and break it up later if i live that long
well seeing as nobody wants it and nobody is just me only then
dump it
otherwise it should be highly portable to all different ANSI Smalltalk
just as soon as the other Smalltalks stop the prehistoric insanity and
allow Method M to be in multiple Categories
or something
and then allow system wide searching on a Category

i could attempt allowing M in multiple Categories in Squeak
     if i could get some help from somebody
     or something
     it should be easy why isn’t it easy?
     is some prehistoric rubble is blocking?
     SSSSSSS HOCK people hate the idea? Now why in hell would you do that
unless i wake up and go oh no i can’t do that I’ve got to do all of this
     clean the gutters watch a million hours of tv etc

On Sat, Nov 26, 2022 at 08:58 Eliot Miranda <eliot.miranda at gmail.com> wrote:

> Hi Tobi,
>
> On Thu, Nov 24, 2022 at 12:18 PM Tobias Pape <Das.Linux at gmx.de> wrote:
>
>> Hi Eliot
>>
>> First things first, I did not raise objections in my admittedly short
>> quip.
>>
>>
>> > On 24. Nov 2022, at 20:23, Eliot Miranda <eliot.miranda at gmail.com>
>> wrote:
>> >
>> > Hi Tobi,
>> >
>> >     let me try again (https://youtu.be/Cj8n4MfhjUc)…
>>
>> :D
>>
>> I already got my comfy chair!
>>
>> >
>> >> On Nov 23, 2022, at 12:23 PM, Tobias Pape <Das.Linux at gmx.de> wrote:
>> >>
>> >> Yet, nil is only seldom a good domain object.
>> >
>> > Precisely. Being disjoint from any domain it is the ideal “I am not a
>> domain object” marker. So when one wants a variable to range over a domain
>> and the singleton “not a member of the domain” nil is a great choice.  And
>> that’s exactly how I use it below.
>>
>> Second things second, I got that.
>>
>> >
>> > There is another excellent marker of a non-domain object, and that is a
>> newly instantiated object. That object is known to not be any other object,
>> since objects are unique.  So if code is searching for something (eg
>> applying a block to every literal in the system), having the newly
>> instantiated object that implements the search use itself as the “I’m not
>> in the domain of all pre-existing objects” is a sensible choice.  This is
>> the pattern InstructionStream uses when scanning for selectors.
>>
>> And #someObject/#nextObject.
>> I get that. And it is actually a beautiful thing you cannot do
>> everywhere[0].
>>
>> My fear is as follows:
>>
>> I hope we can agree that "nil" is part of the "system domain" of
>> Smalltalk, or - said differently - the meta-level.
>>
>> So are the concepts of variables, classes etc.
>>
>
> Yes, and equally, for example, collections. The Set instance in a set of
> accounts is not part of the domain because it's not specific to the
> domain.  It comes from the Smalltalk library.
>
> But so what?  This feels like a straw man to me.  One could argue that an
> account object itself is not part of the domain, but part of the model of
> the domain, etc.
>
> In the end nil is an object that is useful and well-defined.  It isn't
> special, just like true & false aren;t special, or that classes being
> objects aren't special.  Instead these are all functional relationships
> that allow us to construct a system that is malleable and comprehensible.
>
>
>> The non-meta, base, or "domain proper" layer can be anything you want to
>> computationally achieve.[1]
>> Let's arbitrarily chose finance[2].
>>
>> A domain object would be an account, a transaction, an account holder,
>> etc.
>> (Note that we can chose how to represent each, and we do not necessarily
>> need objects for each, but I digress).
>>
>> My take: in code dealing with such domain objects, nil should appear next
>> to never, because it is an object from the Metalevel.
>>
>
> I don't agree. nil can serve as an absence, and absences are important.
>
> In any query which can yield no results we have three choices:
> - answer nil (e.g. at end of stream)
> - raise an exception
> - require passing in a continuation to take in the event of an error (e.g.
> the block argument to at:ifAbsent: or the second one to detect:ifNone: etc)
>
> Often nil is lighter-weight, much more concise, and hence more
> comprehensible, hence to be preferred.
>
> The problems with accepting nil as the general "nothing to see" marker
>> include:
>>
>> - There are too many.
>>   In our example, an account holder could have an instVar "account" which
>> could be nil when not having an account yet, BUT ALSO
>>   an account could have a "closingDate" for when the account folded,
>> which is "nil" when the account is still open, AND ALSO, a transaction
>> could have
>>   an "auditor" which is nil as long as no audit has taken place etc.
>>     Just like that, nil takes _different roles_ just by being convenient.
>>
>
> As do the integers, symbols, collections. As do classes.  Should we have
> different kinds of classes for the class library, the meta level, the
> domain model? Or is it sufficient to have classes, metaclasses and traits?
>  i.e. do we need to label things according to their use, or is it
> sufficient to differentiate them purely by function?  I think the latter.
>
> - Nil has problematic provenance.
>>   When somewhere during debugging (the all-known MNU for UndefinedObject)
>> a nil pops up, it is often reallllly hard to say whence it came from.
>>     So dealing with a lot of nil-bearing code will send you down rabbit
>> holes after the other.
>>
>
> Whereas NaN doesn't have problematical provenance?  Or getting an
> identically-valued instance with a different identity, or a host of other
> potential evils.... These are not specific to nil, and not specific to
> using nuil as a marker of absence, or as bottom.  Programming is tricky; we
> have lots of ways of doping things; things happen very fast; code does what
> tou tell it, not what you want it to do.  We find we make mistakes all the
> time.  This is not specific to the use of nil in our domain models.
>
>> - Nil begets polymorphism, nil defies polymorphism.
>>   It is one of the most awesome feats of Smalltalk that nil is NOT like
>> NULL, in that it can respond to messages. That is exceptionally powerful
>>   and has given Smalltalk a lot of resilience.
>>    But cluttering UndefinedObject with custom, even domain-specifc
>> methods is a really bad idea. However, that means
>>   it is often unwise to just have object that could be nil be sent
>> arbitrary messages.
>>   Hence a multitude of #isNil/#ifNil-Checks. Proper domain objects that
>> model absence, pre-valid state, or error conditions can deal much better
>> with that.
>>
>
> When it's possible then fine.  But in the query example above we must be
> able to deal with absence/have an element disjoint from a domain.  And nil
> functions ideally for this case.
>
> - Nil is in a collection-superposition (just like your good old USB-A plug
>> which you have to turn at least twice to fit).
>>   You only know whether nil _actually_ could be a collection when you
>> know that a non-nil object in its place is a collection [3].
>>   Said differently: in contrast to LISPy languages, our nil is _by
>> design_ no collection, while LISPy null _by design_ IS the empty list.
>>   This makes for funny messages like #isEmptyOrNil, which bails on
>> non-nil-non-collection objects.
>>     So every time you have to deal with nil, you automatically at lease
>> once have to answer the question "could the non-nil version of this object
>> be a collection"?
>>
>
> Many uses of isEmptyOrNil are in response to FillInTheBlank which can
> return nil on cancel or an empty string if the user doesn't type anything.
> This is a natural consequence of the affordances of FillInTheBlank, and
> isEmptyOrNil is simply a pragmatic response, hardly a symptom of some deep
> problem.
>
>
>> There are a lot of interesting approaches to each or combinations of
>> these issues.
>> This includes Null-Object patterns, Sane-default-initializers,
>> exceptions, or explicit models of multiplicity[4].
>>
>> But back to the beginning.
>>
>> In code that does, for example
>>
>> blaFooAnAccount
>>
>>   | fooAccount |
>>   self accounts processBla:
>>     [:ea |
>>     fooAccount ifNil: [fooAccount := ea].
>>     fooAccount := (ea doesBork: fooAccount)
>>       ifTrue: [fooAccount]
>>       ifFalse: [ea]]
>>   ^ fooAccount
>>
>> we find two things:
>>
>
> I think we find three things. The things you8 list below, plus the fact
> that this should have been written using detect:ifNone: ;-)
>
>>
>> First, we could inadvertently return nil from that method. But this is
>> technical and I think most here can deal with that.
>>
>> But second, the line "fooAccount ifNil: [fooAccount := ea]." ACTUALLY says
>>
>>   "if fooAccount is an uninitialized temporary variable, populate it".
>>
>> This is technically correct, but conflates domains.
>> In our world of finance, the idea of a "temporary variable" does no make
>> sense. It is part of the meta-level domain, the system.
>>
>> I don't say this is wrong _per se_ but people reading, and even more so,
>> people writing such code
>> MUST be aware that they are crossing domains, and especially, entering a
>> meta level.
>>
>> That's why I think these warnings are really ok.
>> I won't fight the commit "Compiler-eem.480.mcz", especially since it more
>> or less is descriptive of a pervasive style of writing Smalltalk of Squeak
>> Core contributors.
>>
>> I hope people find theses ideas useful.
>>
>> Best regards
>>         -Tobias
>>
>>
>> [0]: I've used it in Python code to much joy.
>> [1]: Caveat lector: the "domain layer" can surely be the "system layer".
>> In fact that is what a lot of system code deals with.
>>      But this is messy for our considerations above and lets treat it as
>> _exceptional_.
>> [2]: Semi-arbitrarly, just because I received my tax returns :P
>> [3]: yes, that is a strange sentence. It's late. Also, Ardbeg.
>> [4]: For example, as in the work of Steimann (
>> https://dl.acm.org/doi/10.1145/2509578.2509582 ). It seems they had a
>> Smalltalk implementation in 2017.
>>
>>
>> >
>> >> -t
>> >>
>> >>> On 23. Nov 2022, at 19:34, tim Rowledge <tim at rowledge.org> wrote:
>> >>>
>> >>> I won't quote it all again but what Eliot wrote is important. There
>> are good solid reasons why Smalltalk has a rigorously defined
>> UndefinedObject. We demand rigorously defined areas of doubt and
>> uncertainty!
>> >>>
>> >>> tim
>> >
>> >
>> > _,,,^..^,,,_ (phone)
>> >
>>
>>
>>
>>
>
> --
> _,,,^..^,,,_
> best, Eliot
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20221126/e5c67964/attachment-0001.html>


More information about the Squeak-dev mailing list