Pharo-dev
By thread
pharo-dev@lists.pharo.org
By month
Messages by month
- ----- 2026 -----
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
February 2015
- 1068 messages
Re: [Pharo-dev] Parsing float difference between 2.0 and 3.0, was it on purpose?
by Nicolas Cellier
2015-02-06 16:18 GMT+01:00 Marcus Denker <marcus.denker(a)inria.fr>:
>
> > On 06 Feb 2015, at 11:45, Yuriy Tymchuk <yuriy.tymchuk(a)me.com> wrote:
> >
> > We have merged the parsers into one, because we had 3 parsers that
> didnât have any dedicated use-cases, juts were developed historical as at
> some point someone needed a bit more functionality, and then different
> parsers were used randomly on the system.
>
> Yes, it was quite hard to understand what was going on. And it is strange
> to have 3 different parsers for numbers...
>
>
No it's not strange.
2 different parsers respond to 2 different syntax and expectations.
To me it's quite clear:
- The SmalltalkNumberParser was there to parse a Smalltalk syntax
(badly named SqNumberParser in the ages...)
It should do this thru Number readSmalltalkSyntaxFrom: '1.0e4'
- The ExtendedNumberParser was there to parse an extended syntax
(the one most apps handling data from oustide world will wish to parse).
It should do this thru Number readFrom: '1.0e+4'
- The FortranNumberParser was just an unused experiment.
Its sole goal was to expose an example of how a GenericNumberParser could
be subclassed.
Such class has a better place in a cook-book than in the image, so Bye
bye.
Date readFrom: '2015/02/06' readStream does not have to follow a Smalltalk
syntax, so why Number readFrom: '1.0e+4' readStream would have to?
As Yuriy underlined, we might extend the Smalltalk syntax to embrasse some
of external world patterns, why not, but it's limited and is going to be a
problem with formats like '.2' or '2.e0'.
Whether the extended parser should be in the core image or not is a valid
question.
We all agree that Pharo is all but finished and need to be constantly
cleaned up.
The challenge is how can Pharo change but remain
application-writer-friendly?
So two different things are:
- the value of the feature: is it worth maintaining it or not?
If yes, should it be maintained outside the core, or inside by the
Pharo-team?
I agree that removing incomplete features is a valid strategy when the
team is too small
- the quality of implementation
And there are two ways of cleaning:
- clean a dirty implementation, but keep the feature (eventually with a
different API)
- remove the feature, based on a value/cost analysis
Here, I feel like it's the dictatorship which sounds questionnable.
Were the feature understood?
There were unit tests and class comments, so pretending to not understand
is not really an excuse.
Were the value of the features discussed?
Maybe in a small core team... From outside, we don't really know.
Were an externalisation of the feature and transfer of maintenance to a 3rd
party discussed?
I'm not aware of. I'm sure it would have been a better decision.
So from my POV, such decision process remains to improve. It sounds too
light and arbitrary.
In some cases, I have the impression that the volunty of cleaning is too
much dogmatic.
I agree that too much pragmatism won't lead to a clean image any time
soon...
I agree that Pharo team has a licence to change things and should decide,
otherwise let's all stick to Squeak ;)
But a bit of democratie, argumentation and COORDINATION does not hurt.
Then how can user support be improved?
- Is it possible to write release notes helping the transition?
(were is located the add-on package that enables compatibility, who
maintains it, is there a new and better API, etc...)
- Could some automated AST-based refactorings be prepared and applied
auto-magically?
It's not necessarily the sole business of Pharo-team, user community could
help writing such notes.
Nicolas
> As for the expression - yes we have to decide about it. If itâs only
> about being able to use exponent in float literals, one can use: âNumber
> readFrom: '2.5850009999999998e04ââ. If itâs about being similar to the
> other languages, we can also decide does it make sense to have a +2 literal.
> >
> If it makes no problems with backward compatibility, why not have both?
>
> > Uko
> >
> >> On 06 Feb 2015, at 09:04, Marcus Denker <marcus.denker(a)inria.fr> wrote:
> >>
> >>
> >>> On 06 Feb 2015, at 09:02, stepharo <stepharo(a)free.fr> wrote:
> >>>
> >>>
> >>> Le 5/2/15 10:40, Sven Van Caekenberghe a écrit :
> >>>>> On 05 Feb 2015, at 10:36, Ben Coman <btc(a)openInWorld.com> wrote:
> >>>>>
> >>>>> I personally would prefer to be able to use exponents. No sure what
> the big picture is.
> >>>>> cheers -ben
> >>>> Of course exponents are still supported ;-)
> >>>>
> >>>> The discussion is about the + sign for positive exponents. I am not
> sure, but I think that traditional Smalltalk did not support this, but it
> was added to support common practice in other languages. Now it is
> apparently gone again, probably not on purpose.
> >>>
> >>> I do not know I think that marcus removed it to avoid to have two
> parsers in the image.
> >>>
> >>
> >> Maybe this was a mistakeâ¦
> >>
> >> Marcus
> >
> >
>
>
>
Feb. 6, 2015
Re: [Pharo-dev] ||
by Thierry Goubier
Hi Ben,
2015-02-06 16:03 GMT+01:00 Ben Coman <btc(a)openinworld.com>:
>
>
> On Fri, Feb 6, 2015 at 5:58 PM, Thierry Goubier <thierry.goubier(a)gmail.com
> > wrote:
>
>> Hi Eliot,
>>
>> maybe I'll frame the core question a bit differently, thanks to your
>> explanations.
>>
>> I see pragmas used mainly for two things:
>>
>> 1- expressing a link to some metadata used by low level tools: compiler,
>> C lang generator, etc... primitives for me are part of that. Kind of neat
>> to see that unified.
>>
>
>
> btw, I just used a pragma to solve this issue of getting correct debugger
> behaviour for halting and stepping over #halt statements [1]. There seem
> about a dozen methods that can cause a #halt spread between Object and Halt
> classes which should all behave similarly, so the options would seem
> * hardcode all these methods either into to check for in
> Halt>>signalerContext (or into a helper method called from #singalerContext)
> * have a convention for a certain protocol to hold these methods, which
> Halt>>signalerContext can look up (except currently the methods on Object
> are an extension protocol)
> * tag each such method with a pragma. This simplified the solution a
> lot. The search of the call stack just asked each method if it had the
> <debuggerCompleteToSender> pragma.
>
Yes, I agree with your assessment. Solution 2 require multiple protocols
for a single method to be extensible, and this usage is perfect for
metadata associated with the method.
>
> I think discoverability is an issue with pragmas. From Nautilus you can't
> "see" which methods contain which pragmas. I wonder if one solution for
> this would be for pramga methods to be grouped under a <virtual-protocol>
> in the third pane of Nautilus.
>
> [1] https://pharo.fogbugz.com/default.asp?12970
>
The good old finder has a pragmas search mode which allows for a bit of
discoverability (pragma users), but it doesn't link to the code exploiting
the pragmas.
Do you know if we have something specific on SmartSuggestions for pragmas?
Thierry
Feb. 6, 2015
Re: [Pharo-dev] Switching to Pharo from Visualworks
by Thierry Goubier
2015-02-06 17:05 GMT+01:00 Ben Coman <btc(a)openinworld.com>:
>
>
> @General, btw is it possible to have more levels in the package pane, so
> that all the AST packages appear under a single first level entry "AST" ?
>
Yes @Ben, but it's not yet in Nautilus. I have a few experiments in that in
AltBrowser, such as:
- pre-existing hierarchical categories for packages (with about 5 to 20
entries),
- naming-based matching (i.e. all AST packages are under AST),
[image: Images intégrées 1]
- catalogKeyword-based categories (for configurations with keyword entries,
they are moved in the right top-level package category),
- configuration naming based category creation (see above), and
- user adjustable hierarchies (i.e. you can reorganize the tree if you
prefer and save it as a setting).
Some of it needs some improvement, because configurations are often not
that well organised (many don't have keywords at all), naming conventions
in configurations aren't reliable, and I don't grok Monticello/Metacello
well enough to explore configurations and baselines the way Versionner does.
Bringing that to Nautilus may not be that easy. The left pane is fairly
narrow, and not very tall due to the filter box (which could auto-hide
instead of being allways there). The same goes for the 6 panes idea: it's
very wide and, compared to the past, we're dealing with longuer entries
(icons, indentation) which translate into larger panes.
Thierry
Feb. 6, 2015
Re: [Pharo-dev] SmallInteger asByteArray for negative numbers
by David T. Lewis
>
> I was going to complain about expecting such niceties as a built in
> 2s-complement rather than program it myself (I am a bit rusty on such
> matters), but when I look what should I find?
>
> (-123 asTwosComplement: 16rFFFFFFFF) asByteArray. "=> #[255 255 255
> 133]"
>
> cheers -ben
>
Hi Ben,
You might want to look at http://www.squeaksource.com/TwosComplement
Dave
Feb. 6, 2015
Re: [Pharo-dev] ||
by Eliot Miranda
Hi Thierry,
On Fri, Feb 6, 2015 at 9:29 AM, Eliot Miranda <eliot.miranda(a)gmail.com>
wrote:
>
>
> On Fri, Feb 6, 2015 at 1:58 AM, Thierry Goubier <thierry.goubier(a)gmail.com
> > wrote:
>
>> Hi Eliot,
>>
>> maybe I'll frame the core question a bit differently, thanks to your
>> explanations.
>>
>> I see pragmas used mainly for two things:
>>
>> 1- expressing a link to some metadata used by low level tools: compiler,
>> C lang generator, etc... primitives for me are part of that. Kind of neat
>> to see that unified.
>>
>
> There's a third use that is, I think, the most powerful. Maybe you see
> this as the same as 1, but I don't. The method is a component to be
> included in some larger structure, e.g. it is an action method on a menu,
> or it is an implementation of a pane in an inspector. The pragma is the
> message to be sent to the object that manipulates that larger structure to
> add the method to it. This is how menu pragmas work in VW. There is an
> object called a MenuBuilder. To add a method to a menu (and which menu is
> described by the pragma) the menu builder sets the method as its current
> method and then performs the pragma. The parameters in the pragma allow
> the MenuBuilder to add the method in the right way to the menu. But the
> execution of the pragma is what actually adds the mehtod to the menu. So
> its a combination of specification and execution.
>
> 2- categorizing things in a decoupled, package-extension compatible way.
>>
>> I still think there is something in the design that bother me. 1- and 2-
>> are convention-based, so as is most of Smalltalk anyway, so diregarding
>> another approach to 2- as convention-based is a bit dishonest: pragmas get
>> more authority because they look like they have been integrated in the
>> language definition compared to competing solutions.
>>
>
> Yes, it's right to say they have been integrated (but no documented).
>
> No, this is just because I start to wonder if methods shouldn't have a bit
>> more in that "define, add and manipulate" metadata idea, i.e. make it more
>> explicit and start to have tools which represent methods as more like
>> objects and not only text items (methods having metadata, additional slots
>> or instance variables, counters, statistics, ast, traces, break points,
>> etc...). And, in a way, a need to have two levels of execution: one which
>> happens at compile time (i.e. when one accept a method), one which happens
>> at runtime.
>>
>
> I think whether methods are objects or text is in the eye of the
> beholder. From my perspective methods /are/ objects. The textual display
> and compilation of them is only the conventional programmer view of them.
> Bu from a system perspective methods are objects. Look for example at all
> the debugger machinery. That is largely concerned with bytecodes in method
> objects.
>
> For that, I think pragmas are a start, but they are not the complete
>> answer. And I think we should solve the package-extension compatible thing
>> in 2- to not have 2- (which is just for me a plain categorisation issue)
>> polluting the design by introducing additional/unrelated requirements.
>>
>
> I have no problem with your criticism of pragmas used for categorisation.
> Method categories are already there and sometimes much more appropriate
> than pragmas. For example, in the SPur bootstrap the methods to be added
> or modified in Spur are included in categories of SpurBootstrapPrototypes
> and its subclasses. If there were pragmas in these methods then the
> pragmas would be copied into Spur, which is not at all what I want.
> Instead I copy across the methods in the relevant categories.
>
> But this "not a complete solution" feels to me an unfair criticism.
> Pragmas are what they are and they can do a lot. But no part of the system
> does everything. A system is composed of components.
>
Or are you talking about the lack of class pragmas? This is a point. But
classes already have an executable hook they can use for system
modification, their class-side initialize and obsolete methods. That's
been used for a long time to address system modification needs on
installing and removing classes. So form that perspective there's less of
a need to class pragmas. Instead we're focussing on more specialised class
definition facilities such as slots, which are intrinsic to classes, i.e.
define the class itself, rather than pragmas, which are extrinsic to
methods in that they define how methods interact in the system outside
themselves.
>
>
>>
>> 2015-02-05 22:47 GMT+01:00 Eliot Miranda <eliot.miranda(a)gmail.com>:
>>
>>> Hi Thierry,
>>>
>>> A block is far more difficult to deal with than a pragma. A pragma has
>>> a simple key, its selector, and simple access to its arameters, the
>>> arguments. A block is opaque. Essentially it can only be executable.
>>> Pragmas are both executable and function as annotations.
>>>
>>
>> Pragmas are executable, but in a context which is not visible at the
>> place they are written.
>>
>>
>>>
>>>
>>>
>>>> I strongly agree with your keep it in sync argument, still. Pragmas are
>>>> better than nothing.
>>>>
>>>>>
>>>>>
>>>>> There is no such need with pragmas; they are always in sync with the
>>>>> methods they describe because they are embedded in their methods. Instead
>>>>> we can use triggering to do useful things, adding a pane to open inspectors
>>>>> as soon as we define the method that describes the pane, adding or removing
>>>>> a menu entry, etc.
>>>>>
>>>>
>>>> Just a naming convention does just that perfectly fine, and with less
>>>> lines (except for extensions by external packages) and faster code in many
>>>> cases.
>>>>
>>>
>>> Yes, but there end up being lots of naming conventions and they are
>>> non-obvious. Whereas pragmas, because they are in-your-face in the methods
>>> in question, don't need conventions. They just need documenting ;-).
>>>
>>
>> They are still conventions which needs documentation. Pragmas are, in
>> allmost all uses, indirections (i.e. a tag meaning something to a far away
>> object), and the meaning associated to a pragma is, in every case, a
>> roll-your-own solution. And they are clearly "in your face" :)
>>
>>
>>>
>>>
>>> That's not necessarily true. Some pragmas do cause processing at
>>> compile time. For example, an FFI signature pragma can be checked at
>>> compile-time. But it's in keeping with smalltalk that type checking is not
>>> performed at compile time in most cases, isn't it? Why should one require
>>> that pragmas be semantically checked at compile time when normal SMalltalk
>>> code isn't? At least one knows that the message instance the pragma is
>>> compiled to is a valid object and *can* be performed. So pone does know at
>>> least that the pragma is executable. Obviously whether that ability to be
>>> executed only becomes potent with the right receiver. So any compiled
>>> pragma as the potential to be usefully evaluated.
>>>
>>
>> Ok, but its all fuzzy.
>>
>> It may be executed, but it may be not.
>>
>> It may send an error if incorrect, but it may fail silently.
>>
>> It may be executed at compile time, it may be executed sometime later
>> triggered by the compilation, or it may be executed at runtime, as if it
>> was normal code. And of course it may not be executed at all ...
>>
>> You see what I mean?
>>
>>
>>>
>>> And often it doesn't matter if the pragma reference a completely non
>>>> existent method or api, since it is probably never executed by anybody (and
>>>> if it is, it won't probably reify the error message properly as a
>>>> compilation error as it should, because it may be triggered miles away from
>>>> the system browser).
>>>>
>>>
>>>
>>> There is lots about Smalltalk that is non-obvious, about programming in
>>> general that is non-obvious. I don't see that as a specific criticism of
>>> pragmas. Once one knows the idiom it is easy to use; its wide-spread use
>>> is evidence of that. And hopefully this conversation will help make it
>>> more obvious :-). That it is limited is also not perhaps a useful
>>> criticism. The issue is whether it is adequate. I think it is. A literal
>>> message goes a long way. I'e not heard of complaints about limitations so
>>> far. Do you have specific examples where pragmas are inadequate? The
>>> tools /do/ support them. One can do senders and implementors in the
>>> browser and see the methods that include them, and the implementors of
>>> pragmas. browseAllSelect: will narrow down the search. There is an API
>>> for programmatic use (pragmasDo: et al).
>>>
>>
>> See [*][**] for the tools support. For me, pragmas, even in their
>> definition, have serious semantic issues. If they were strictly, as you
>> describe them, a metadata API access executed at compile time, then they
>> would be a lot stronger.
>>
>> Make them sent at compile-time on the method object, and that would
>> probably solve all the true arguments I have against them :)
>>
>> for example: <worldMenu> against <tagAndAnnounce: #worldMenu>; <tag:
>> #gtInspectorExtension> instead of <gtInspectorExtension>, etc...
>>
>> (<tagAndAnnounce:> would gain a bit of performance, as well).
>>
>> Thierry
>>
>> [*] Searching a bit for menu pragmas in a Pharo image seems to return a
>> bit of a mess. There is so many of them, all differents, and interestingly,
>> this does not return the code triggered (or using) them, which makes
>> discovery of what the pragma is used for (and its parameters) an
>> 'interesting' problem.
>>
>> I suggest a task then: an illustrated sequence of how to search for the
>> code triggering world menu addition of a new command, for someone which is
>> new to Pharo ;)
>>
>> [**] even when used for categorisation, the API is prone to bugs, such as
>> having a method without pragma overriding a superclass method with pragma
>> because they have the same name.
>>
>>
>>
>
>
> --
> best,
> Eliot
>
--
best,
Eliot
Feb. 6, 2015
Re: [Pharo-dev] ||
by Eliot Miranda
Hi Frank,
On Fri, Feb 6, 2015 at 2:29 AM, Frank Shearar <frank.shearar(a)gmail.com>
wrote:
> On 5 February 2015 at 21:20, Thierry Goubier <thierry.goubier(a)gmail.com>
> wrote:
> >
> >
> > 2015-02-05 21:28 GMT+01:00 Eliot Miranda <eliot.miranda(a)gmail.com>:
> >>
> >>
> >>
> >> On Thu, Feb 5, 2015 at 11:34 AM, Thierry Goubier
> >> <thierry.goubier(a)gmail.com> wrote:
> >>>
> >>>
> >>>
> >>> 2015-02-05 18:51 GMT+01:00 Eliot Miranda <eliot.miranda(a)gmail.com>:
> >>>>
> >>>>
> >>>>
> >>>> On Thu, Feb 5, 2015 at 2:31 AM, Thierry Goubier
> >>>> <thierry.goubier(a)gmail.com> wrote:
> >>>>>
> >>>>>
> >>>>>
> >>>>> 2015-02-05 10:55 GMT+01:00 Sven Van Caekenberghe <sven(a)stfx.eu>:
> >>>>>>
> >>>>>> It is obviously a compromise (or a continuum) between abstractions
> and
> >>>>>> performance.
> >>>>>
> >>>>>
> >>>>> I agree. With a special view in that we are in a sub domain where
> >>>>> simple things well designed (Smalltalk, that is) are amazingly good
> at
> >>>>> supporting complex designs.
> >>>>>
> >>>>>>
> >>>>>>
> >>>>>> But there should remain a focus on efficiency (not just speed but
> also
> >>>>>> memory), it is hard to fix these things years later.
> >>>>>
> >>>>>
> >>>>> And I like the fact that efficient code and design is often a
> pleasure
> >>>>> to read and learn from :)
> >>>>>
> >>>>> Now, being radical: could we get rid of pragmas ? The only reason I
> see
> >>>>> to them is that they allow extension by external packages, because
> we can't
> >>>>> have methods which belong to two protocols (*).
> >>>>
> >>>>
> >>>> They are a Smalltalk-centric way of adding arbitrary metadata to
> >>>> methods; Smalltalk-centric in that a pragma is a Message instance,
> may be
> >>>> queried for senders, performed, etc, and that it can be parsed using
> the
> >>>> standard compiler (they add no new syntax). They have been broadly
> used.
> >>>> IME they have simplified and reduced code where ever they have been
> used.
> >>>> They don't have to be there but they're a good thing. Why do you
> want to
> >>>> get rid of them?
> >>>
> >>>
> >>> Because the "they have simplified and reduced code where ever they have
> >>> been used" is wrong. I just have to give you a counter example:
> >>
> >>
> >> OK, the claim is too strong. But they /have/ simplified code in cases
> >> where they're appropriate. And I can cite several examples.
> >>
> >>>
> >>>
> >>> One of the uses of pragmas is associating methods containing Gui
> commands
> >>> or settings to specific objects. Based on an object inspected or
> selected,
> >>> you search among all its methods the ones containing a specific pragma
> (and
> >>> you order them by a parameter to that pragma, if you want), and you
> execute
> >>> that method to retrieve the objects you want (presentations, menu
> commands,
> >>> shortcuts, you name it, I use it :)).
> >>>
> >>> The code to do that is exactly as long as the one which, on the same
> >>> object, retrieve all methods under a certain protocol (the latter being
> >>> faster than the pragma one, to boot).
> >>>
> >>> Each method is one line longer ("the pragma").
> >>>
> >>> Each such method usually has in its name a copy of the pragma
> >>> (gtInspectorXXX methods, I'm looking at you), because of course this
> is far
> >>> more user friendly to indicate its purpose in the method name than in
> only
> >>> the pragma.
> >>>
> >>> (There are two more arguments for the use of pragmas in that context,
> one
> >>> which has a direct counter-example, one which hasn't: )
> >>>
> >>> Moreover, the semantic of pragmas is "interesting" to describe, and in
> >>> some cases, require a good amount of dark magic about a global object
> >>> listening to all methods changes and capturing (and executing) certain
> >>> methods in a vague relation about when this is going to happen, or
> being
> >>> triggered on specific system events (main menu rebuilding, anyone?).
> The
> >>> funny thing is to see that pattern visible on a profile when loading
> >>> packages (talk of a scalable approach).
> >>
> >>
> >> But triggering in the background happens for maintaining change sets,
> >> notifying other clients too. It's not as if pragmas introduced such
> >> triggering; that kind of triggering has been in use for a long time.
> And
> >> being able to reshape the GUI automatically is very useful.
> >
> >
> > I don't contest the possibilities, it's just that they add a significant
> > layer of complexity when non mastered (how many Pharo developpers know
> which
> > event you have to register to to receive all new methods notifications?
> Is
> > that documented in one of the books?), and that, except for using them as
> > <primitives> or for extensibility, I see other syntaxes and smalltalk
> code
> > which are simpler.
> >
> > A good example is that the pragma syntax is never included in the one
> page
> > Smalltalk syntax description :)
> >
> >>
> >>
> >>>
> >>>
> >>>>
> >>>> (and yes, I'm biassed)
> >>>
> >>>
> >>> Then you're the right person to give me counter arguments...
> >>>
> >>> (Now, I'd look differently at pragmas used for gradual typing and so
> >>> on... But even for something like FFI, I'd seriously prefer to have
> >>> Smalltalk calls to describe the call and its arguments than a kind of
> script
> >>> hidden inside pragmas, just for the discoverability and because it
> makes one
> >>> less idiom to deal with)
> >>
> >>
> >> Why? A good use of pragmas is to associate meta data with a particular
> >> method. Having calls off to the side always introduces the need for
> >> book-keeping to keep those methods off to the side in sync with the
> methods
> >> they're describing. Typically everyone rolls their own. But here we're
> >> adding a level of triggering just to keep the metadata methods in sync.
> >
> >
> > I agree with the "metadata", but I'd prefer a executable, evaluate that
> > block as a medata literal than the pragma. Something that says
> > "onceAndStoreAsMetadata", to a block, for example. An API to compiled
> > methods which says add metadata.
> >
> > I strongly agree with your keep it in sync argument, still. Pragmas are
> > better than nothing.
> >
> >>
> >>
> >> There is no such need with pragmas; they are always in sync with the
> >> methods they describe because they are embedded in their methods.
> Instead
> >> we can use triggering to do useful things, adding a pane to open
> inspectors
> >> as soon as we define the method that describes the pane, adding or
> removing
> >> a menu entry, etc.
> >
> >
> > Just a naming convention does just that perfectly fine, and with less
> lines
> > (except for extensions by external packages) and faster code in many
> cases.
> >
> >>
> >>
> >> This is one idiom that covers a host of other cases. That's why I claim
> >> that whenever I've seen it used it has reduced complexity.
> >>
> >> Some history. Steve Dahl, I developed pragmas at ParcPlace, with
> Vassili
> >> Bykov adding abstractions for accessing them. The first step was to
> replace
> >> some ugly class-side code to set unwind bits in ensure: and
> ifCurtailed: by
> >> a pragma the compiler would recognise and set the bits itself. The
> first
> >> real use was to make the VisualWorks launcher's menus extensible.
> Before
> >> pragmas the launcher's menu was static and had lots of disabled entries
> for
> >> launching tools that were sold separately such as DLLAndCConnect. With
> >> pragmas the launcher's menu was defined with the base system's tools and
> >> then extended as each tool package was loaded, or cut-back as each tool
> was
> >> unloaded. So that decoupled the launcher from introducing new tools. A
> >> nice result.
> >>
> >> We then started using it for the browser and one could plug-in a single
> >> tool without redefining the browser's menu methods, which decoupled each
> >> extension. All this was done in the context of the parcel system,
> where we
> >> could rapidly load packages (parcels ~= Fuel). Pragmas allowed us to
> >> decouple these tools where they collided in places like menu definition,
> >> tool registration.
> >>
> >> Then Tami Lee, who was managing the COM connection that turned a VW
> image
> >> into a COM server, became the first "user" of pragmas outside of myself
> and
> >> Steve. She used it to replace a lot of class-side methods that defined
> the
> >> signatures of methods that comprised the server. It was a lovely
> clean-up.
> >> One could define the COM signature for a method in the method itself,
> and
> >> the class side lost about three separate methods that defined all that
> >> metadata. One could read the server method itself and understand its
> >> semantics without having to consult the class-side methods. One didn't
> have
> >> to know that there was metadata hidden on the class side because it was
> >> right there in your face.
> >>
> >> Then Vassili used it for his cool inspector framework, Trippy, which was
> >> similar to Glamour in some ways, and was a huge improvement over the old
> >> Inspector framework, again resulting in a much more pluggable,
> decoupled and
> >> extensible system. Vassili also added the abstractions for accessing
> >> pragmas in methods.
> >>
> >> Then we added checking so that one could restrict the compiler to accept
> >> only legal pragmas for a given class. But if we defined the legal
> pragmas
> >> in a class-side method, say legalPragmas, then this would be exactly the
> >> kind of single point for extensions that causes collisions between
> packages,
> >> each of which might want to add its own set of pragmas. The
> solution... use
> >> a pragma to mark a class-side method as defining a set of legal pragmas
> for
> >> a class. One could have more than one method defining a set of legal
> >> pragmas; packages wishing to add their own cool pragmas were decoupled.
> >> Once the system because recursive, it had to be a good idea ;-).
> >
> >
> > Ok, I start to see where the abstraction wasn't working so well... since
> > pragmas are not executed, when writing a method you can't know if the
> pragma
> > is correct, because even executing the method may not trigger the pragma
> > induced code. So you need the legalPragmas to give metadata on metadata
> for
> > the compiler to do a bit of static checking, but it doesn't work for
> > system-wide pragmas unless you extend Object :(
> >
> > And often it doesn't matter if the pragma reference a completely non
> > existent method or api, since it is probably never executed by anybody
> (and
> > if it is, it won't probably reify the error message properly as a
> > compilation error as it should, because it may be triggered miles away
> from
> > the system browser).
>
> Pragmas don't execute. They're _data_. There is no "calls unknown
> sender" because the don't execute.
>
I think they can do both, which is nice. I actually prefer uses of pragmas
where they /are/ executable. They ca be performed by some object, and that
execution can modify the system in the desired way, for example having a
menu builder perform the menu definition pragma in a menu action method to
add that action to a menu.
> Eliot's point is that pragmas _describe_, and then other systems act
> on those descriptions.
>
Right. But that description is executable by something else. Unlike, for
example, a block as metadata which is only executable.
> They're just like Java or C# attributes, or Python decorators. Only
> they're better, because Java/C# attributes can do anything, whereas
> pragmas merely describe.
>
Are you sure Java and C# attributes are executable? When I read the
wikipedia page for Java attributes I get the notion that they're structured
non-executable data, i.e.:
"When Java source code is compiled, annotations can be processed by
compiler plug-ins called annotation processors. Processors can produce
informational messages or create additional Java source files or resources,
which in turn may be compiled and processed, and also modify the annotated
code itself. The Java compiler conditionally stores annotation metadata in
the class files, if the annotation has aRetentionPolicy of CLASS or
RUNTIME. Later, the JVM or other programs can look for the metadata to
determine how to interact with the program elements or change their
behavior.
In addition to processing an annotation using an annotation processor, a
Java programmer can write their own code that uses reflections to process
the annotation. Java SE 5 supports a new interface that is defined in the
java.lang.reflect package. This package contains the interface called
AnnotatedElement that is implemented by the Java reflection classes
including Class, Constructor, Field,Method, and Package. The
implementations of this interface are used to represent an annotated
element of the program currently running in the Java Virtual Machine. This
interface allows annotations to be read reflectively."
The microsoft doc on C# indicates that they're declarative, but no mention
of those declarations being executable:
"C# enables programmers to invent new kinds of declarative information,
called attributes. Programmers can then attach attributes to various
program entities, and retrieve attribute information in a run-time
environment. For instance, a framework might define a HelpAttribute
attribute that can be placed on certain program elements (such as classes
and methods) to provide a mapping from those program elements to their
documentation."
> frank
>
> >> There are other uses; you've seen them. I used them in VMMaker to
> >> eliminate metadata that was embedded as sends to methods defined as
> ^self
> >> that Slang had to extract and analyse, and filter-out from generated
> code.
> >> They simplified Slang's code anaylsis, made the simulator more efficient
> >> (since there were no longer sends to execute). My point is that in all
> the
> >> cases I've seen, using pragmas has
> >> - simplified the code
> >> - made it obvious that methods have metadata associated with them
> >> - replaced specialized ways of associating metadata with code by the
> >> general pragma mechanism
> >> and in many of the cases it has
> >> - provided a more decoupled system
> >> - provided a more dynamic and extensible system
> >
> >
> > Yes, and I can point out some of its shortcomings: it's non-obvious, it's
> > limited, tools, even that many years later don't support them well (in
> > Squeak or Pharo, at least), its redundant in quite a few variants.
> >
> > Please, could we improve a bit? Methods belonging to multiple protocols
> > would give us the same decoupling as pragmas, and I would be free to
> avoid
> > them where I shouldn't have to use them :)
> >
> >>
> >>
> >> I've been meaning to write up the history of pragmas for ages, but
> >> Vassili, Steve or I have always been too busy. I think a community
> paper on
> >> their use and history would be worth-while, and might go a long way to
> >> reduce antipathies like yours. I will forever be in debt to anyone who
> >> wants to volunteer to help me write such a paper.
> >
> >
> > That would certainly be interesting :)
> >
> >>
> >>
> >>>
> >>>
> >>> Thierry
> >>>
> >>> (Look. I started using Smalltalk in 1992... and up to your
> description, I
> >>> wasn't aware pragmas were supposed to follow message syntax ;) Thanks
> for
> >>> the explanation, by the way)
> >>
> >>
> >> They /have/ to follow literal message syntax. t's all the compiler will
> >> accept. That's why there needs to be a paper.
> >
> >
> > Yes!
> >
> > Thanks for taking the time to argument,
> >
> > Thierry
> >
> >>
> >>
> >>
> >> --
> >> best,
> >> Eliot
>
>
--
best,
Eliot
Feb. 6, 2015
Re: [Pharo-dev] ||
by Eliot Miranda
On Fri, Feb 6, 2015 at 1:58 AM, Thierry Goubier <thierry.goubier(a)gmail.com>
wrote:
> Hi Eliot,
>
> maybe I'll frame the core question a bit differently, thanks to your
> explanations.
>
> I see pragmas used mainly for two things:
>
> 1- expressing a link to some metadata used by low level tools: compiler, C
> lang generator, etc... primitives for me are part of that. Kind of neat to
> see that unified.
>
There's a third use that is, I think, the most powerful. Maybe you see
this as the same as 1, but I don't. The method is a component to be
included in some larger structure, e.g. it is an action method on a menu,
or it is an implementation of a pane in an inspector. The pragma is the
message to be sent to the object that manipulates that larger structure to
add the method to it. This is how menu pragmas work in VW. There is an
object called a MenuBuilder. To add a method to a menu (and which menu is
described by the pragma) the menu builder sets the method as its current
method and then performs the pragma. The parameters in the pragma allow
the MenuBuilder to add the method in the right way to the menu. But the
execution of the pragma is what actually adds the mehtod to the menu. So
its a combination of specification and execution.
2- categorizing things in a decoupled, package-extension compatible way.
>
> I still think there is something in the design that bother me. 1- and 2-
> are convention-based, so as is most of Smalltalk anyway, so diregarding
> another approach to 2- as convention-based is a bit dishonest: pragmas get
> more authority because they look like they have been integrated in the
> language definition compared to competing solutions.
>
Yes, it's right to say they have been integrated (but no documented).
No, this is just because I start to wonder if methods shouldn't have a bit
> more in that "define, add and manipulate" metadata idea, i.e. make it more
> explicit and start to have tools which represent methods as more like
> objects and not only text items (methods having metadata, additional slots
> or instance variables, counters, statistics, ast, traces, break points,
> etc...). And, in a way, a need to have two levels of execution: one which
> happens at compile time (i.e. when one accept a method), one which happens
> at runtime.
>
I think whether methods are objects or text is in the eye of the beholder.
>From my perspective methods /are/ objects. The textual display and
compilation of them is only the conventional programmer view of them. Bu
from a system perspective methods are objects. Look for example at all the
debugger machinery. That is largely concerned with bytecodes in method
objects.
For that, I think pragmas are a start, but they are not the complete
> answer. And I think we should solve the package-extension compatible thing
> in 2- to not have 2- (which is just for me a plain categorisation issue)
> polluting the design by introducing additional/unrelated requirements.
>
I have no problem with your criticism of pragmas used for categorisation.
Method categories are already there and sometimes much more appropriate
than pragmas. For example, in the SPur bootstrap the methods to be added
or modified in Spur are included in categories of SpurBootstrapPrototypes
and its subclasses. If there were pragmas in these methods then the
pragmas would be copied into Spur, which is not at all what I want.
Instead I copy across the methods in the relevant categories.
But this "not a complete solution" feels to me an unfair criticism.
Pragmas are what they are and they can do a lot. But no part of the system
does everything. A system is composed of components.
>
> 2015-02-05 22:47 GMT+01:00 Eliot Miranda <eliot.miranda(a)gmail.com>:
>
>> Hi Thierry,
>>
>> A block is far more difficult to deal with than a pragma. A pragma has a
>> simple key, its selector, and simple access to its arameters, the
>> arguments. A block is opaque. Essentially it can only be executable.
>> Pragmas are both executable and function as annotations.
>>
>
> Pragmas are executable, but in a context which is not visible at the place
> they are written.
>
>
>>
>>
>>
>>> I strongly agree with your keep it in sync argument, still. Pragmas are
>>> better than nothing.
>>>
>>>>
>>>>
>>>> There is no such need with pragmas; they are always in sync with the
>>>> methods they describe because they are embedded in their methods. Instead
>>>> we can use triggering to do useful things, adding a pane to open inspectors
>>>> as soon as we define the method that describes the pane, adding or removing
>>>> a menu entry, etc.
>>>>
>>>
>>> Just a naming convention does just that perfectly fine, and with less
>>> lines (except for extensions by external packages) and faster code in many
>>> cases.
>>>
>>
>> Yes, but there end up being lots of naming conventions and they are
>> non-obvious. Whereas pragmas, because they are in-your-face in the methods
>> in question, don't need conventions. They just need documenting ;-).
>>
>
> They are still conventions which needs documentation. Pragmas are, in
> allmost all uses, indirections (i.e. a tag meaning something to a far away
> object), and the meaning associated to a pragma is, in every case, a
> roll-your-own solution. And they are clearly "in your face" :)
>
>
>>
>>
>> That's not necessarily true. Some pragmas do cause processing at compile
>> time. For example, an FFI signature pragma can be checked at
>> compile-time. But it's in keeping with smalltalk that type checking is not
>> performed at compile time in most cases, isn't it? Why should one require
>> that pragmas be semantically checked at compile time when normal SMalltalk
>> code isn't? At least one knows that the message instance the pragma is
>> compiled to is a valid object and *can* be performed. So pone does know at
>> least that the pragma is executable. Obviously whether that ability to be
>> executed only becomes potent with the right receiver. So any compiled
>> pragma as the potential to be usefully evaluated.
>>
>
> Ok, but its all fuzzy.
>
> It may be executed, but it may be not.
>
> It may send an error if incorrect, but it may fail silently.
>
> It may be executed at compile time, it may be executed sometime later
> triggered by the compilation, or it may be executed at runtime, as if it
> was normal code. And of course it may not be executed at all ...
>
> You see what I mean?
>
>
>>
>> And often it doesn't matter if the pragma reference a completely non
>>> existent method or api, since it is probably never executed by anybody (and
>>> if it is, it won't probably reify the error message properly as a
>>> compilation error as it should, because it may be triggered miles away from
>>> the system browser).
>>>
>>
>>
>> There is lots about Smalltalk that is non-obvious, about programming in
>> general that is non-obvious. I don't see that as a specific criticism of
>> pragmas. Once one knows the idiom it is easy to use; its wide-spread use
>> is evidence of that. And hopefully this conversation will help make it
>> more obvious :-). That it is limited is also not perhaps a useful
>> criticism. The issue is whether it is adequate. I think it is. A literal
>> message goes a long way. I'e not heard of complaints about limitations so
>> far. Do you have specific examples where pragmas are inadequate? The
>> tools /do/ support them. One can do senders and implementors in the
>> browser and see the methods that include them, and the implementors of
>> pragmas. browseAllSelect: will narrow down the search. There is an API
>> for programmatic use (pragmasDo: et al).
>>
>
> See [*][**] for the tools support. For me, pragmas, even in their
> definition, have serious semantic issues. If they were strictly, as you
> describe them, a metadata API access executed at compile time, then they
> would be a lot stronger.
>
> Make them sent at compile-time on the method object, and that would
> probably solve all the true arguments I have against them :)
>
> for example: <worldMenu> against <tagAndAnnounce: #worldMenu>; <tag:
> #gtInspectorExtension> instead of <gtInspectorExtension>, etc...
>
> (<tagAndAnnounce:> would gain a bit of performance, as well).
>
> Thierry
>
> [*] Searching a bit for menu pragmas in a Pharo image seems to return a
> bit of a mess. There is so many of them, all differents, and interestingly,
> this does not return the code triggered (or using) them, which makes
> discovery of what the pragma is used for (and its parameters) an
> 'interesting' problem.
>
> I suggest a task then: an illustrated sequence of how to search for the
> code triggering world menu addition of a new command, for someone which is
> new to Pharo ;)
>
> [**] even when used for categorisation, the API is prone to bugs, such as
> having a method without pragma overriding a superclass method with pragma
> because they have the same name.
>
>
>
--
best,
Eliot
Feb. 6, 2015
Re: [Pharo-dev] [Slots] Invisible Slots
by Marcus Denker
> On 06 Feb 2015, at 11:50, Marcus Denker <marcus.denker(a)inria.fr> wrote:
>
>>
>> Next: When building classes with Slots, the class builder need to call back on the slot and hand the class to each. Then the slot
>> can reflectively change the class, e.g. the PropertySlot will check if there is already a hidden property base slot and if not, add it
>> reflectively).
>
> This is now done:
>
> https://pharo.fogbugz.com/f/cases/14876/Add-call-back-in-ClassBuilder-to-ca…
>
For playing with this, in 479:
InstanceVariableSlot subclass: #AccessorSlot
slots: { }
classVariables: { }
category: âPackage'
two methods, #installingIn and #removingFrom:, which are called by the class builder:
installingIn: aClass
| reader writer |
reader := String streamContents: [ :str |
str
nextPutAll: self name;
cr;tab;
nextPutAll: ' ^';
nextPutAll: self name.
].
writer := String streamContents: [ :str |
str
nextPutAll: self name;
nextPutAll: ': anObject';
cr;tab;
nextPutAll: self name;
nextPutAll: ':= anObject.'.
].
aClass compile: reader classified: 'accessing'.
aClass compile: writer classified: 'accessingâ.
removingFrom: aClass
aClass removeSelector: self name.
aClass removeSelector: self name asMutator.
Now we can make a class and see how the accessors are automatically added (and removed when the slot is removed):
Object subclass: #TT
slots: { #tttt => AccessorSlot }
classVariables: { }
category: âPackage'
NOTE: this is an example of what can be done with Slots. It is *not* an example of what *should* be done with Slots.
(this we only will know after using them for a while).
Marcus
Feb. 6, 2015
Re: [Pharo-dev] [pharo-project/pharo-core] 6a5096: 40477
by Ben Coman
My first thought is that it may expose some other bug previously hidden,
but that could just be bravado. It is late here, so I will take a look
tomorrow.
cheers -ben
On Fri, Feb 6, 2015 at 11:24 PM, Sven Van Caekenberghe <sven(a)stfx.eu> wrote:
> I see it as well from time to time in #40478 but not often and it does not
> seem to have any negative effect, I can just keep on working and there is
> no obvious slowdown.
>
> > On 06 Feb 2015, at 16:23, Marcus Denker <marcus.denker(a)inria.fr> wrote:
> >
> >
> >> On 06 Feb 2015, at 09:07, Marcus Denker <marcus.denker(a)inria.fr> wrote:
> >>
> >>>>
> >>>> Log Message:
> >>>> -----------
> >>>> 40477
> >>>>
> >>>> 14669 Delay refactoring (part 2a) - avoid UI locking up when timer
> event loop is stopped
> >>>> https://pharo.fogbugz.com/f/cases/14669
> >>>>
> >>>>
> >>>>
> >>>> Thanks Max and Marcus for review and pushing this through.
> >>>>
> >
> > It seems to have some problem:
> >
> > WorldState>>#interCyclePause: failed
> > https://pharo.fogbugz.com/f/cases/14874
> >
> > When e.g. in Nautilus searching for a class.
> >
> > Marcus
>
>
>
Feb. 6, 2015
Re: [Pharo-dev] SmallInteger asByteArray for negative numbers
by Nicolas Cellier
One more thing: accessing the integer bytes means accessing the details of
internal representation...
But if you look a bit deeper, you'll discover that:
- SmallInteger use 2-complement internally (not accounting for immediate
tag bits)
- LargeInteger use sign-magnitude internally.
So to maintain some uniformity at Integer level, and having all kind of
sub-instances behaving identically, we have to cheet.
As Sven said, in 2-complement we could model the high bits as an infinite
sequence of 1... Not convenient for converting to a finite ByteArray, so we
have chosen to behave as if integers were sign-magnitude encoded...
Funnily, for bit-ops (bitAnd: bitOr: etc...) we have chosen another
paradigm: behave as if integers were 2-complement encoded.
2015-02-06 15:48 GMT+01:00 Sven Van Caekenberghe <sven(a)stfx.eu>:
> Alejandro,
>
> > On 06 Feb 2015, at 15:10, Alejandro Infante <
> alejandroinfante91(a)gmail.com> wrote:
> >
> > Hello,
> > I have just found that calling asByteArray for any negative small
> integer returns the same result that the positive small integer. Is it
> supposed to be like that or is it a bug?
> >
> > 1 asByteArray = -1 asByteArray. "true"
> >
> > (1 to: 100000) allSatisfy: [ :int | int asByteArray = int negated
> asByteArray ] âtrue"
> >
> > Cheers,
> > Alejandro
>
> (These kinds of questions should be asked on pharo-users(a)lists.pharo.org)
>
> You can only represent positive numbers as ByteArrays, because to
> represent negative numbers you have to decide how to do that. The most
> common solution is to use 2-complement. To do this you also need to decide
> on the number of bytes to use.
>
> Here is an example using 4 bytes:
>
> | integer size mask |
> integer := -123.
> size := 4.
> mask := (2 raisedTo: size * 8) - 1.
> (mask bitAnd: ((integer abs bitXor: mask) + 1))
> asByteArrayOfSize: 4.
>
> => #[255 255 255 133]
>
> => FF FF FF 85
>
> The reverse is:
>
> | integer size mask |
> integer := #[255 255 255 133] asInteger.
> size := 4.
> mask := (2 raisedTo: size * 8) - 1.
> (mask bitAnd: ((integer abs bitXor: mask) + 1))
> negated
>
> This is for negative numbers.
>
> Positive numbers need not be 2-complemented.
>
> When decoding, integers < (2 raisedTo: (size * 8) - 1) are negative.
>
> HTH,
>
> Sven
>
>
>
Feb. 6, 2015