Re: Proposal for Packages (Was: The art of Unix Programming in
The new % would solve some problems and you are right about the mapcar thing which can be annoying. However the ambiguity as to which class is controlling the behavior of func% remains but can perhaps be mitigated by yet another convention requiring you to put the context call in a special place, like in the er.l file of a project or some such? On Tue, Sep 6, 2011 at 12:05 AM, Alexander Burger wrote: > On Mon, Sep 05, 2011 at 05:50:07PM +0200, Alexander Burger wrote: > > ... > >(class +Add) > > > >(dp foo% (X Y) > > (+ X Y) ) > > > >(dp bar% (X Y Z) > > (+ X Y Z) ) > > BTW, another serious drawback with the (foo> '+Cls ) approach is > that you can't easily do some things which make Lisp so powerful, which > you can do with a function like 'foo%', e.g > > (mapcar 'foo% ..) > > Instead, you must write a full anonymous function > > (mapcar '((X) (foo> '+Cls X)) ..) > > Same with 'apply', 'pass' etc. > > Cheers, > - Alex > -- > UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe >
Re: Proposal for Packages (Was: The art of Unix Programming in
On Mon, Sep 05, 2011 at 05:50:07PM +0200, Alexander Burger wrote: > ... >(class +Add) > >(dp foo% (X Y) > (+ X Y) ) > >(dp bar% (X Y Z) > (+ X Y Z) ) BTW, another serious drawback with the (foo> '+Cls ) approach is that you can't easily do some things which make Lisp so powerful, which you can do with a function like 'foo%', e.g (mapcar 'foo% ..) Instead, you must write a full anonymous function (mapcar '((X) (foo> '+Cls X)) ..) Same with 'apply', 'pass' etc. Cheers, - Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Proposal for Packages (Was: The art of Unix Programming in
Hi Henrik, > The only objection I have against this is that it now becomes impossible to > know if a certain function is global or not, and if not, to know which class > it belongs, from simply looking at the invocation. True. For that reason I first used a new convention using the '%' character for functions defined with 'dp' (as opposed to the '>' for normal methods): (class +Add) (dp foo% (X Y) (+ X Y) ) (dp bar% (X Y Z) (+ X Y Z) ) I found it too verbose after all. Perhaps a matter of taste. Not knowing certain details of a definition by just looking at it is the normal case for other functions and methods too. When a message is sent to an object (foo> Obj), you also can't tell from just a static inspection. In case of (foo Args) the situation should be relatively clear from the preceding 'context' call. > Instead of using the class functionality in a basically static way like I > often do it would then maybe be better to simply impose a new convention > which could read something like this: > > "If you find yourself doing something in a way that would constitute a class > with only static methods and no member variables in another language then > you should dispense with the class and instead do (de classname.funcname ()) > instead of public methods and (de "funcname" ()) instead of private > methods." Agreed. > To sum it up: making use of the fact that PicoLisp is perhaps the most > forgiving language when it comes to what characters are allowed in function > names should be exploited further instead of creating new constructs that > add complexity to the language. > > We already have conventions where we use ?, " and > in names, we can have > more. Right. I would propose the above '%' convention then. Cheers, - Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Proposal for Packages (Was: The art of Unix Programming in
The only objection I have against this is that it now becomes impossible to know if a certain function is global or not, and if not, to know which class it belongs, from simply looking at the invocation. I think this is a dangerous step towards too much magic that might create confusion and logical bugs. Instead of using the class functionality in a basically static way like I often do it would then maybe be better to simply impose a new convention which could read something like this: "If you find yourself doing something in a way that would constitute a class with only static methods and no member variables in another language then you should dispense with the class and instead do (de classname.funcname ()) instead of public methods and (de "funcname" ()) instead of private methods." The above then forces the programmer to think and plan before coding, as opposed to what I'm doing now when I simply go for classes because it gives me a maximum of future options at the expense of overly verbose syntax and code that executes slower. To sum it up: making use of the fact that PicoLisp is perhaps the most forgiving language when it comes to what characters are allowed in function names should be exploited further instead of creating new constructs that add complexity to the language. We already have conventions where we use ?, " and > in names, we can have more. /Henrik Sarvell On Mon, Sep 5, 2011 at 7:46 PM, Alexander Burger wrote: > Hi all, > > On Mon, Sep 05, 2011 at 08:17:04AM +0200, Alexander Burger wrote: > > A call like > > > >(foo> '+Pckg ) > > > > is in no regard more encapsulating the namespace then > > > >(foo.Pckg ) > > > > but it is more tedious to write and read, takes up two cells more than > > the second (4 versus 2), and eats up performance at each call for the > > method lookup. > > If people like to stick with this way of building packages from classes, > how about the following proposal? > > It still has the same performance handicap as the straight-forward usage > of classes and methods, but it provides for some syntactic sugar, and > does not impose the cell space penalty. > > I would call it "Dynamic Packages", because it does a dynamic runtime > lookup, like in Henrik's style, but with a less noisy syntax. > > > 1. I would put these three expressions into "lib.l" > > # Dynamic packages > (off "Context") > > (de context Lst > (setq "Context" Lst) ) > > (de dp "Args" > (push *Class "Args") > (let "@Msg" (car "Args") > (def "@Msg" >(curry ("@Msg") @ > (if (method '"@Msg" '"Context") > (pass @) > (quit "Not in context" '"@Msg") ) ) ) ) ) > > > 2. Then we can define "packages", e.g. '+Add' and '+Mul'. Note that such > packages are still just normal classes, allowing class variables, > subclasses, inheritance etc. The difference is only that methods are > not defined with 'dm' (define method) but with 'dp' (define package > function): > > (class +Add) > > (dp foo (X Y) > (+ X Y) ) > > (dp bar (X Y Z) > (+ X Y Z) ) > > > (class +Mul) > > (dp foo (X Y) > (* X Y) ) > > (dp bar (X Y Z) > (* X Y Z) ) > > > 3. Later, package search order can be specified with 'context'. > 'context' takes any number of classes, to be searched sequentially > from left to right: > > (context +Add +Mul) > > (println (foo 3 4) (bar 2 3 4))# Prints 7 9 > > > (context +Mul +Add) > > (println (foo 3 4) (bar 2 3 4))# Prints 12 24 > > > One disadvantage of this mechanism (in addition to the runtime overhead) > is that functions defined with 'dp' can only be EXPRs (i.e. evaluating > all arguments). > > Any opinions? > > Cheers, > - Alex > -- > UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe >
Re: Proposal for Packages (Was: The art of Unix Programming in
On Mon, Sep 05, 2011 at 02:46:54PM +0200, Alexander Burger wrote: > 1. I would put these three expressions into "lib.l" > ... >(de dp "Args" > (push *Class "Args") > (let "@Msg" (car "Args") > (def "@Msg" > (curry ("@Msg") @ >(if (method '"@Msg" '"Context") > (pass @) > (quit "Not in context" '"@Msg") ) ) ) ) ) The invocation of dynamic package functions can be sped up considerably if we use 'send' directly (at the expense of a perhaps less beautiful error message): (de dp "Args" (push *Class "Args") (let "@Msg" (car "Args") (def "@Msg" (curry ("@Msg") @ (pass send '"@Msg" '"Context") ) ) ) ) Cheers, - Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe