[Cuis-dev] unnecessary punctuation

Luciano Notarfrancesco luchiano at gmail.com
Fri Jun 14 05:57:39 PDT 2024


IMO, it is usually fine to use the same selector with different meanings in
different classes, its not always bad (IMO) and it makes code nicer to read
and selectors easier to guess (for a new user). But when a subclass down
the hierarchy redefines a message with a totally different meaning it is
wrong (IMO). So the selectors we put in Object are kind of global, we
cannot change the meaning of #printOn: or #= or #hash in one of our classes
or things will break. That’s why it seems to me that its better to keep
Object as small as possible and perhaps remove Object>>#value. I think we
already talked about this tho, and we didnt remove it, was it because
dependencies or events rely on it?

On Fri, Jun 14, 2024 at 19:24 Jaromir Matas via Cuis-dev <
cuis-dev at lists.cuis.st> wrote:

> Hi,
> My understanding is that this:
>
>  >> [Boris] The meaning of BlockClosure>>value and Association>>value
> have  nothing in common!
>
> is the source of the confusion here; many definitions of #value are not
> "redefinitions" of Object>>value, they are often just simple accessors
> to instance variables called #value.
>
> Do the accessors "spoil the fun"? It's the kind of ("fake") polymorphism
> not available in most languages. Is it good or bad?
>
> And back to the original Mark's question (roughly) - why would it be bad
> to modify the compiler so that
>
> `cond ifTrue: a ifFalse: b`
>
> is treated the same way as
>
> `cond ifTrue: [a] ifFalse: [b]`
>
> i.e. optimized using bytecode jumps rather than sending #ifTrue:ifFalse:
> ?
>
> The divergence of b problem would disappear and we'd just have to be
> aware of the different semantics (#value send when used without [ ])...
>
> At any rate the current behavior of #ifTrue:ifFalse: feels inconsistent
> - depending on the "type" of arguments (or the syntactic form).
>
> A side-effect of "legitimizing" this approach would be one could start
> using (or "abusing"?) it like:
>
> a := Association key: 'one' value: 1.
> b := Association key: 'two' value: 2.
> x := cond ifTrue: a ifFalse: b
>
> and expecting x = 1 or x = 2. Too bad?
>
> Or one could assign blocks to a and b:
>
> a := [1].
> b := [2]
> x := cond ifTrue: a ifFalse: b
>
> Is it bad to expect  x = 1 or x = 2 ?
>
> I haven't noticed this inconsistency before Mark's question and I'm
> confused now - apologies in case the above doesn't make much sense :)
>
> Best,
> Jaromir
>
>
> On 14-Jun-24 11:16:28 AM, "Boris Shingarov via Cuis-dev"
> <cuis-dev at lists.cuis.st> wrote:
>
> >>  It is *expected* of blocks to understand *#value*. There is no
> concern; if
> >>  you redefine *BlockClosure >> value*, the image will crash.
> >
> >Not sure what you mean here.  The very first thing we do in PreSmalltalks
> >before we begin to build MachineArithmetic, libGDBs etc *is* we
> >redefine BlockClosure>>value (to auto-curry when invoked with the wrong
> >number of arguments).  I am guessing what you mean is "redefine in a way
> >*incompatible* with the live system", but that's a characteristic of
> >how liveness is implemented in one particular Smalltalk, not of #value.
> >
> >>  Right, it’s not a good idea to implement value in Object like this, it
> >>  doesnt really generalize anything, I suggest we remove it.
> >
> >This, on the other hand, *will* break all hell, because now you are
> >doing computation in a category without products; and one immediate
> >consequence of that, is that Lawvere's elements-as-morphisms no longer
> >work.
> >
> >In more detail:
> >
> >A (Smalltalk) Object (which we might want to rename to Point or at least
> >SetElement if we were really radical) is a morphism from the product of
> >zero multiplicands to that (categorical) object.  In other words, it is
> >an entity responding to 0-arg #value.  So if I were on a radical course
> >to clean-up Object's protocol, #value and #yourself would be the two
> >messages I would keep.
> >
> >>    x := cond ifTrue: a ifFalse: b.
> >>
> >>  you might be in for a surprise
> >
> >Yes, exactly that.
> >So the problem with the above code is not that it's "twice slower" but
> >that it's simply not equivalent to the other one, due to order of
> >evaluation.  On the one hand, in Smalltalk-80 there is no easy way to
> >tell whether a block/method is a function or a partial function or an
> >action; on the other hand, Smalltalk is applicative-order: so what if
> >say b diverges?  Then
> >
> >   1 < 2 ifTrue: [a] ifFalse: [b]
> >
> >evaluates to ≅a, but
> >
> >   1 < 2 ifTrue: a ifFalse: b
> >
> >diverges.  A similar trouble happens when b has a side effect.
> >
> >>  a surprise if you happen to pass in a or b that implements value
> >
> >Hmm, yeah, that's an interesting one, let's see:
> >
> >   x >= 0 ifTrue: a ifFalse: b                  (1)
> >
> >and let's assume x∈ℤ so x>=0 can't be anything other than a True
> >or a False (in unmodified Smalltalk-80 such as vanilla Cuis we don't
> >have unsaturated terms, so this works).  So this endows ℤ with a
> >simple algebra of types:
> >
> >   ℤ = ( (ℤ | [ :x | x>=0 ]) + (ℤ | [ :x | x<0 ) )       (2)
> >
> >so what we are doing in (1) is we are raising to the (2) degree,
> >and because (2) is a sum, (1) is a product of A×B (those are types
> >of a and b, even though Smalltalk-80 does not provide an explicit
> >notation for them).  So we are just precomposing A>>value
> >and B>>value before the diagram for ifTrue:ifFalse:, and it HAS
> >to go from () to A / to B, and it can ONLY return self (per the
> >definition of "element").  Aha!  So I would be inclined to guess
> >that we are just looking at plain bogus implementors of #value.
> >Let's look what we have in Cuis.  Aha: Association>>value.  Wow.
> >I can't think of a better example of what in a conversation some
> >time ago on this list we were calling "fake polymorphism".
> >The meaning of BlockClosure>>value and Association>>value have
> >nothing in common!
> >
> >... now this got me curious... what other interesting code lurks
> >among the implementors of #value...  ha, MessageSend>>value
> >special-cases nil arguments vs empty arguments, this smells to
> >Lisp's generalized-false, and I wonder if we can normalize that?
> >Just for kicks and giggles, let's see where the special-case may be
> >used... oh, if I remove it, Cuis dies spectacularly opening a
> >million debuggers in WorldMorph>>runLocalStepMethods:...
> >would be interesting to probe how deep that rabbit hole goes...
> >
> >--
> >Cuis-dev mailing list
> >Cuis-dev at lists.cuis.st
> >https://lists.cuis.st/mailman/listinfo/cuis-dev
> --
> Cuis-dev mailing list
> Cuis-dev at lists.cuis.st
> https://lists.cuis.st/mailman/listinfo/cuis-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20240614/a3c51e12/attachment.htm>


More information about the Cuis-dev mailing list