Re: [Pharo-users] Hmmm sending at:put: to an undefined object (nil) gives a confusing error message

2019-03-13 Thread Richard O'Keefe
Byte arrays are not host specific.  True.
But integers are not byte arrays.  They don't even contain byte arrays.
Just like (boxed) Floats are not word arrays and don't contain word arrays.

For what it's worth, I find that it's quite unusual for a method to
change from private to public or vice versa.

The basic problem with putting methods in a "private" category is
that it has no actual effect.  It was Smalltalk that taught me OO and
the importance of encapsulation.  But Smalltalk doesn't actually
support encapsulation.  Every detail of the implementation of
Dictionary, for example, is exposed.  And the practice of
"self-encapsulation" is actually ANTI-encapsulation for this reason.

Now there are several ways to implement hashed collections.
The one I've had for years is pleasantly fast and pleasantly
free of weird restrictions (keys/elements can be nil and why
not).  I've got a new one I'm working on that uses less space
and is faster still.  Because my dialect *enforces* encapsulation,
when my testing is complete, I'll be able to swap the new
version in, knowing that no external code can possibly depend on
the implementation details.obj

As a particular example, it was only when I implemented
serialisation (nowhere up to Fuel's standards, of course) that
I implemented #pvtInstVarAt:[put:] and an object is *still*
completely and exclusively in charge of its own instance
variables.

I agree that using a prefix is not the best way to do this,
but the eye soon learns to skip over it.  It's not that much
worse than "Inst" or "Var" or the pervasive and obtrusive
use of prefixes on selectors in VisualAge Smalltalk.  I think
Pharo would be the better for having *some* way to enforce
encapsulation, but what the best way is I don't claim to know.

On Wed, 13 Mar 2019 at 21:35, K K Subbu  wrote:

> On 13/03/19 12:45 PM, Richard O'Keefe wrote:
> > Base 256: that's an implementation detail.
> > Little-endian: that's an implementation detail.
>
> Architecture-specific no. Implementation yes. But that should be fine
> for private methods.
>
> > My Smalltalk uses base 65536 native-endian and
> > takes some care not to let Smalltalk code find out.
> > (Not least because on 64-bit machines I want to
> > use base 2**32.)
>
> This would make it host-specific. Byte arrays are not host-specific.
>
> > For *private* methods, depending on otherwise
> > hidden implementation details is fair enough.
> > My Smalltalk picked up a convention from Squeak
> > -- or rather, from the Squeak mailing list --
> > that a 'pvt' prefix on a selector makes it truly
> > private and *enforces* that.  Pharo does not seem
>
> pvt prefix is possibly inspired by Hungarian notation. I find that it
> impairs readability and maintenance. Should a method change from private
> to public or vice versa down the line, maintenance will be a nightmare.
> My own preference is placing them in 'private' category (or even
> private-* categories).
>
> > to have anything similar, and #at: is the epitome
> > of a selector in extremely wide general use.
> > Since #digitAt: exists -- and is what the integer
> > classes use -- it is practically certain that #at:
> > is sent to an integer only by mistake.
>
> You make a good point here. Perhaps #at:/#at:put: should throw an error
> for all numbers and private methods could use basic versions instead.
>
> Regards .. Subbu
>
>


Re: [Pharo-users] Hmmm sending at:put: to an undefined object (nil) gives a confusing error message

2019-03-13 Thread K K Subbu

On 13/03/19 12:45 PM, Richard O'Keefe wrote:

Base 256: that's an implementation detail.
Little-endian: that's an implementation detail.


Architecture-specific no. Implementation yes. But that should be fine 
for private methods.



My Smalltalk uses base 65536 native-endian and
takes some care not to let Smalltalk code find out.
(Not least because on 64-bit machines I want to
use base 2**32.)


This would make it host-specific. Byte arrays are not host-specific.


For *private* methods, depending on otherwise
hidden implementation details is fair enough.
My Smalltalk picked up a convention from Squeak
-- or rather, from the Squeak mailing list --
that a 'pvt' prefix on a selector makes it truly
private and *enforces* that.  Pharo does not seem


pvt prefix is possibly inspired by Hungarian notation. I find that it 
impairs readability and maintenance. Should a method change from private 
to public or vice versa down the line, maintenance will be a nightmare. 
My own preference is placing them in 'private' category (or even 
private-* categories).



to have anything similar, and #at: is the epitome
of a selector in extremely wide general use.
Since #digitAt: exists -- and is what the integer
classes use -- it is practically certain that #at:
is sent to an integer only by mistake.


You make a good point here. Perhaps #at:/#at:put: should throw an error 
for all numbers and private methods could use basic versions instead.


Regards .. Subbu



Re: [Pharo-users] Hmmm sending at:put: to an undefined object (nil) gives a confusing error message

2019-03-13 Thread Richard O'Keefe
It's supposed to be on GitHub but I botched it.


On Wed, 13 Mar 2019 at 21:08, Sven Van Caekenberghe  wrote:

>
>
> > On 13 Mar 2019, at 08:15, Richard O'Keefe  wrote:
> >
> > My Smalltalk
>
> Where can I have a look at that ?
>
>


Re: [Pharo-users] Hmmm sending at:put: to an undefined object (nil) gives a confusing error message

2019-03-13 Thread Sven Van Caekenberghe



> On 13 Mar 2019, at 08:15, Richard O'Keefe  wrote:
> 
> My Smalltalk

Where can I have a look at that ?



Re: [Pharo-users] Hmmm sending at:put: to an undefined object (nil) gives a confusing error message

2019-03-13 Thread Richard O'Keefe
Base 256: that's an implementation detail.
Little-endian: that's an implementation detail.
My Smalltalk uses base 65536 native-endian and
takes some care not to let Smalltalk code find out.
(Not least because on 64-bit machines I want to
use base 2**32.)
For *private* methods, depending on otherwise
hidden implementation details is fair enough.
My Smalltalk picked up a convention from Squeak
-- or rather, from the Squeak mailing list --
that a 'pvt' prefix on a selector makes it truly
private and *enforces* that.  Pharo does not seem
to have anything similar, and #at: is the epitome
of a selector in extremely wide general use.
Since #digitAt: exists -- and is what the integer
classes use -- it is practically certain that #at:
is sent to an integer only by mistake.


On Wed, 13 Mar 2019 at 17:18, K K Subbu  wrote:

> On 12/03/19 9:25 AM, Richard O'Keefe wrote:
> > Squeak where (20 factorial at: 1) answers 0 (oh dear oh dear oh
> > dear).
>
> Richard,
>
> Could you please elaborate on why this is an error?
>
> Large integers are place value encoded (base 256 little endian) and
> stored in byte arrays, so they need #at:/#at:put: (as private methods).
> Place value encoding is not architecture-specific so it doesn't affect
> portability of an image.
>
> Regards .. Subbu
>
>


Re: [Pharo-users] Hmmm sending at:put: to an undefined object (nil) gives a confusing error message

2019-03-13 Thread Richard O'Keefe
Let's start with portability.
I have ST/X, VAST, VW, Squeak, Pharo, GST,
Dolphin, and some minor systems.
GST and ST/X do not define #at: on any kind of
integer at all.  Why would they?  #basicAt:
will do the job, will it not?
Dolphin defines #at:[put:] on Integer as
self shouldNotImplement
and so does VW.

In VAST,
20 at: 1 => primitive failed
20 factorial at: 1 => 2192834560

In Squeak and Pharo,
20 at: 1 => not indexable
20 factorial at: 1 => 0

So sending #at: to an integer is not portable
between mainstream Smalltalk systems, and for
those Smalltalks that define it on large
integers, the value is not consistent on the
same machine and operating system.


But it is worse than that.  Maybe you do not
care about any Smalltalk but Pharo, and there
is a case to be made for that.  But this
is not consistent with *itself*.
1 at: 1
fails in a 64-bit VM,
where that is a SmallInteger, but
answers 0 in a 32-bit VM,
where that is a LargePositiveInteger.

But it gets *worse*.  Numbers are not
supposed to be mutable.  But in a 32-bit
VM,
  x := 1.
  x at: 1 put: 77.
  x
=> 10077.

I'm sorry, but I had enough grief with
constants that weren't in Fortran 66.

Again, there isn't the slightest need to
define #at:put: on Large...Integers because
#basicAt:put: exists. Indeed, we have
#{basicAt:,at:,digitAt:}[put:] and surely
with #digitAt:[put:] around we can let
#at:[put:] be unimplemented on integers?

There's a conceptual problem with #at: and
#digitAt: as well.  An integer can be viewed
as a sequence of bits, right enough, but in
a language without silly machine-word limits
on integers, it's an *infinite* sequence.
At least, if you define logical operations on
bignums using a 2s-complement model, a
LargePositiveInteger extends infinitely far
with 0s and a LargeNegativeInteger extends
infinitely far with 1s. GST gets this right.
VW gets it right for large positive integers
but wrong for large negative ones (or at
least works on the absolute value without
bothering to explain that).

Ah heck, the whole thing is a mess.





On Wed, 13 Mar 2019 at 17:18, K K Subbu  wrote:

> On 12/03/19 9:25 AM, Richard O'Keefe wrote:
> > Squeak where (20 factorial at: 1) answers 0 (oh dear oh dear oh
> > dear).
>
> Richard,
>
> Could you please elaborate on why this is an error?
>
> Large integers are place value encoded (base 256 little endian) and
> stored in byte arrays, so they need #at:/#at:put: (as private methods).
> Place value encoding is not architecture-specific so it doesn't affect
> portability of an image.
>
> Regards .. Subbu
>
>


Re: [Pharo-users] Hmmm sending at:put: to an undefined object (nil) gives a confusing error message

2019-03-12 Thread K K Subbu

On 12/03/19 9:25 AM, Richard O'Keefe wrote:

Squeak where (20 factorial at: 1) answers 0 (oh dear oh dear oh
dear).


Richard,

Could you please elaborate on why this is an error?

Large integers are place value encoded (base 256 little endian) and 
stored in byte arrays, so they need #at:/#at:put: (as private methods). 
Place value encoding is not architecture-specific so it doesn't affect 
portability of an image.


Regards .. Subbu



Re: [Pharo-users] Hmmm sending at:put: to an undefined object (nil) gives a confusing error message

2019-03-12 Thread Richard O'Keefe
Putting public methods in Object that it cannot honestly support makes
#respondsTo: pretty unreliable.  It is an obsolete practice, because
having Traits means that those methods can be mixed in with (part of)
a single line.

On Wed, 13 Mar 2019 at 03:20, Ben Coman  wrote:

> On Tue, 12 Mar 2019 at 21:56, Marcus Denker 
> wrote:
> >
> > Hi,
> >
> > Yes, I do not like it… I think it is there so that you can just make a
> variable subclass and at: / at:put: will work without
> > having to re-implement them…
>
> So we should consider...
> * how often are variable subclasses created ?  by novices or experts ?
> * how much work is it to reimplement those methods ? how difficult to
> know what needs to be done ?
> * what is the balance
>
> cheers -ben
>
>
> >
> > Marcus
> >
> > On 12 Mar 2019, at 04:55, Richard O'Keefe  wrote:
> >
> > I understand #basicAt:[put:] being in Object, but I never understood
> #at:[put:] being there.
> > GNU Smalltalk:
> > st> nil at: 1
> > Object: nil error: Invalid value nil: object not indexable
> > In my Smalltalk, you get a DNU.
> > In Squeak you get a debugger window with title
> > Error: instances of UndefinedObject are not indexable
> > The same for Boolean, Character, and Integer,
> > except Squeak where (20 factorial at: 1) answers 0 (oh dear oh dear oh
> dear).
> > In VW you get a "Subscript out of bounds" error, which is disappointing,
> > as do true and $a, but a LargePositiveinteger gets #shouldNotImplement.
> >
> >
> > On Tue, 12 Mar 2019 at 15:28, Tim Mackinnon  wrote:
> >>
> >> If you forget to initialise a variable which you thought was a
> Dictionary - you get a confusing error message: "Error: only integers
> should be used as indices” if you try an at:put:
> >>
> >> This is a consequence of having at:put: defined on Object (which is a
> bit nasty)
> >>
> >> Should UndefinedObject at least override this and signal something a
> bit more obvious? This is a common and easily done thing and we don't
> support it very well.
> >>
> >> I just did it in some code, and was scratching my head initially until
> I read the stack properly and realised it was something much simpler than I
> thought I had done.
> >>
> >> Any thoughts on this?
> >
> >
>
>


Re: [Pharo-users] Hmmm sending at:put: to an undefined object (nil) gives a confusing error message

2019-03-12 Thread Ben Coman
On Tue, 12 Mar 2019 at 21:56, Marcus Denker  wrote:
>
> Hi,
>
> Yes, I do not like it… I think it is there so that you can just make a 
> variable subclass and at: / at:put: will work without
> having to re-implement them…

So we should consider...
* how often are variable subclasses created ?  by novices or experts ?
* how much work is it to reimplement those methods ? how difficult to
know what needs to be done ?
* what is the balance

cheers -ben


>
> Marcus
>
> On 12 Mar 2019, at 04:55, Richard O'Keefe  wrote:
>
> I understand #basicAt:[put:] being in Object, but I never understood 
> #at:[put:] being there.
> GNU Smalltalk:
> st> nil at: 1
> Object: nil error: Invalid value nil: object not indexable
> In my Smalltalk, you get a DNU.
> In Squeak you get a debugger window with title
> Error: instances of UndefinedObject are not indexable
> The same for Boolean, Character, and Integer,
> except Squeak where (20 factorial at: 1) answers 0 (oh dear oh dear oh dear).
> In VW you get a "Subscript out of bounds" error, which is disappointing,
> as do true and $a, but a LargePositiveinteger gets #shouldNotImplement.
>
>
> On Tue, 12 Mar 2019 at 15:28, Tim Mackinnon  wrote:
>>
>> If you forget to initialise a variable which you thought was a Dictionary - 
>> you get a confusing error message: "Error: only integers should be used as 
>> indices” if you try an at:put:
>>
>> This is a consequence of having at:put: defined on Object (which is a bit 
>> nasty)
>>
>> Should UndefinedObject at least override this and signal something a bit 
>> more obvious? This is a common and easily done thing and we don't support it 
>> very well.
>>
>> I just did it in some code, and was scratching my head initially until I 
>> read the stack properly and realised it was something much simpler than I 
>> thought I had done.
>>
>> Any thoughts on this?
>
>



Re: [Pharo-users] Hmmm sending at:put: to an undefined object (nil) gives a confusing error message

2019-03-12 Thread Marcus Denker
Hi,

Yes, I do not like it… I think it is there so that you can just make a variable 
subclass and at: / at:put: will work without
having to re-implement them…

Marcus

> On 12 Mar 2019, at 04:55, Richard O'Keefe  wrote:
> 
> I understand #basicAt:[put:] being in Object, but I never understood 
> #at:[put:] being there.
> GNU Smalltalk:
> st> nil at: 1
> Object: nil error: Invalid value nil: object not indexable
> In my Smalltalk, you get a DNU.
> In Squeak you get a debugger window with title
> Error: instances of UndefinedObject are not indexable
> The same for Boolean, Character, and Integer,
> except Squeak where (20 factorial at: 1) answers 0 (oh dear oh dear oh dear).
> In VW you get a "Subscript out of bounds" error, which is disappointing,
> as do true and $a, but a LargePositiveinteger gets #shouldNotImplement.
> 
> 
> On Tue, 12 Mar 2019 at 15:28, Tim Mackinnon  wrote:
> If you forget to initialise a variable which you thought was a Dictionary - 
> you get a confusing error message: "Error: only integers should be used as 
> indices” if you try an at:put:
> 
> This is a consequence of having at:put: defined on Object (which is a bit 
> nasty)
> 
> Should UndefinedObject at least override this and signal something a bit more 
> obvious? This is a common and easily done thing and we don't support it very 
> well.
> 
> I just did it in some code, and was scratching my head initially until I read 
> the stack properly and realised it was something much simpler than I thought 
> I had done.
> 
> Any thoughts on this?



Re: [Pharo-users] Hmmm sending at:put: to an undefined object (nil) gives a confusing error message

2019-03-11 Thread Richard O'Keefe
I understand #basicAt:[put:] being in Object, but I never understood
#at:[put:] being there.
GNU Smalltalk:
st> nil at: 1
Object: nil error: Invalid value nil: object not indexable
In my Smalltalk, you get a DNU.
In Squeak you get a debugger window with title
Error: instances of UndefinedObject are not indexable
The same for Boolean, Character, and Integer,
except Squeak where (20 factorial at: 1) answers 0 (oh dear oh dear oh
dear).
In VW you get a "Subscript out of bounds" error, which is disappointing,
as do true and $a, but a LargePositiveinteger gets #shouldNotImplement.


On Tue, 12 Mar 2019 at 15:28, Tim Mackinnon  wrote:

> If you forget to initialise a variable which you thought was a Dictionary
> - you get a confusing error message: "Error: only integers should be used
> as indices” if you try an at:put:
>
> This is a consequence of having at:put: defined on Object (which is a bit
> nasty)
>
> Should UndefinedObject at least override this and signal something a bit
> more obvious? This is a common and easily done thing and we don't support
> it very well.
> I just did it in some code, and was scratching my head initially until I
> read the stack properly and realised it was something much simpler than I
> thought I had done.
>
> Any thoughts on this?
>