A few questions from a confused lisper

2018-07-12 Thread Johan Persson

Hi, list!

First I'd like to say that I'm having a blast playing around with 
PicoLisp lately. (It only took me about seven years to get around to 
it!) The fact that it exists and work as well as it does is a fresh and 
bold counterpoint to the conventional wisdom of the current programming 
language design canon. I love it.


Anyhow, there are a few things that the Common Lisper in me find a bit 
puzzling:


First off, I'm confused about what the correct way of doing local exits. 
There's no "return" or "return-from" -- instead the closest thing I've 
found is "quit", which is sort of akin to "error" in CL, but without the 
jump into the condition-system. It feels wrong. Is it wrong?


Then there's the conditional exits in "for", "do" and "loop" which 
presents a real problem if you wish to terminate the loop from within a 
sub-clause:


(for X (1 2 3 4 5)
  (let Y (mumble-mumble X)
 (NIL Y (println "this doesn't work"

What's the correct way of doing this? Throw the value and catch it right 
outside of the for-loop?


I'm also a pathological meta-programmer, and the lack of macros doesn't 
bother me as much as I thought it would. However, one thing I miss from 
other lisps is a way of expanding macros. How would I go on about doing 
that in PicoLisp?


/ Johan

--
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe


Re: A few questions from a confused lisper

2018-07-12 Thread Bruno Franco
Well, for the conditional exit in the iterators (for, do, and loop),
I would do something like this:
(use Y
(for X (1 2 3 4 5)
(setq Y (mumble-mumble X))
(NIL Y (println "this does not work")) ) )

Though I'm not sure that is the most elegant way to go XD.

As for the local exits, maybe an example of when you wanted to do one
in picolisp would be useful to point you in the right direction.

And the macros, here's a page that can help you find your way
around not having them:
https://picolisp.com/wiki/?macros

also see the functions 'fill and 'macro.
'fill replaces each occurence of a pattern @Pat with its value in the
list that you give it, and 'macro does the same, but evaluates the
resulting list too.

Hope this helps!


On Thu, Jul 12, 2018 at 1:34 PM Johan Persson  wrote:

> Hi, list!
>
> First I'd like to say that I'm having a blast playing around with
> PicoLisp lately. (It only took me about seven years to get around to
> it!) The fact that it exists and work as well as it does is a fresh and
> bold counterpoint to the conventional wisdom of the current programming
> language design canon. I love it.
>
> Anyhow, there are a few things that the Common Lisper in me find a bit
> puzzling:
>
> First off, I'm confused about what the correct way of doing local exits.
> There's no "return" or "return-from" -- instead the closest thing I've
> found is "quit", which is sort of akin to "error" in CL, but without the
> jump into the condition-system. It feels wrong. Is it wrong?
>
> Then there's the conditional exits in "for", "do" and "loop" which
> presents a real problem if you wish to terminate the loop from within a
> sub-clause:
>
>  (for X (1 2 3 4 5)
>(let Y (mumble-mumble X)
>   (NIL Y (println "this doesn't work"
>
> What's the correct way of doing this? Throw the value and catch it right
> outside of the for-loop?
>
> I'm also a pathological meta-programmer, and the lack of macros doesn't
> bother me as much as I thought it would. However, one thing I miss from
> other lisps is a way of expanding macros. How would I go on about doing
> that in PicoLisp?
>
> / Johan
>
> --
> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>


Re: A few questions from a confused lisper

2018-07-12 Thread Bruno Franco
actually, you could just put the function (mumble-mumble X) in the place
of Y:
(for X (1 2 3 4 5)
(NIL (mumble-mumble X)
(println "this does not work")) )


On Thu, Jul 12, 2018 at 9:27 PM Bruno Franco 
wrote:

> Well, for the conditional exit in the iterators (for, do, and loop),
> I would do something like this:
> (use Y
> (for X (1 2 3 4 5)
> (setq Y (mumble-mumble X))
> (NIL Y (println "this does not work")) ) )
>
> Though I'm not sure that is the most elegant way to go XD.
>
> As for the local exits, maybe an example of when you wanted to do one
> in picolisp would be useful to point you in the right direction.
>
> And the macros, here's a page that can help you find your way
> around not having them:
> https://picolisp.com/wiki/?macros
>
> also see the functions 'fill and 'macro.
> 'fill replaces each occurence of a pattern @Pat with its value in the
> list that you give it, and 'macro does the same, but evaluates the
> resulting list too.
>
> Hope this helps!
>
>
> On Thu, Jul 12, 2018 at 1:34 PM Johan Persson  wrote:
>
>> Hi, list!
>>
>> First I'd like to say that I'm having a blast playing around with
>> PicoLisp lately. (It only took me about seven years to get around to
>> it!) The fact that it exists and work as well as it does is a fresh and
>> bold counterpoint to the conventional wisdom of the current programming
>> language design canon. I love it.
>>
>> Anyhow, there are a few things that the Common Lisper in me find a bit
>> puzzling:
>>
>> First off, I'm confused about what the correct way of doing local exits.
>> There's no "return" or "return-from" -- instead the closest thing I've
>> found is "quit", which is sort of akin to "error" in CL, but without the
>> jump into the condition-system. It feels wrong. Is it wrong?
>>
>> Then there's the conditional exits in "for", "do" and "loop" which
>> presents a real problem if you wish to terminate the loop from within a
>> sub-clause:
>>
>>  (for X (1 2 3 4 5)
>>(let Y (mumble-mumble X)
>>   (NIL Y (println "this doesn't work"
>>
>> What's the correct way of doing this? Throw the value and catch it right
>> outside of the for-loop?
>>
>> I'm also a pathological meta-programmer, and the lack of macros doesn't
>> bother me as much as I thought it would. However, one thing I miss from
>> other lisps is a way of expanding macros. How would I go on about doing
>> that in PicoLisp?
>>
>> / Johan
>>
>> --
>> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
>>
>


Re: A few questions from a confused lisper

2018-07-12 Thread Alexander Burger
Hi Johan,

> First off, I'm confused about what the correct way of doing local exits.
> There's no "return" or "return-from" -- instead the closest thing I've found
> is "quit", which is sort of akin to "error" in CL

Correct. There is no 'return' function jumping directly out of a nested
structure. There are, however, 'catch' and 'throw', which implement the same
mechanism (cleaning up all necessary stuff before doing the exit) - just not
syntactically as neat as a simple 'return'.

I use NIL as the catch tag in such cases, e.g.

   (de foo (Args)
  (catch NIL
 (while (something)
(let (A (bar)  B (mumble))
   (racker
  (for I A
 (when (lt0 (+ I B))
(throw) ) ) ) ) ) ) )

Here (throw) corresponds to a (return).

To return a value like (return 7) do (throw NIL 7).


The reason for not having a 'return' function is that it has to do a lot of
cleanup till it reaches the exit (unbind variables, close files and other
dynamic environments). This is initialized and set up by 'catch'.

When a function starts to run, the interpreter does not know yet that there
might be a call to 'return' somewhere deeply nested inside. So it would need to
setup the catch environment for *every* function. This would be too expensive,
as most functions will never call 'return'.

Instead, it is done the PicoLisp way: Let the programmer be in control! Just
insert '(catch NIL' at the beginning of a function (or at any other place).

If you insist, you can create your own return function:

   (de return (Val)
  (throw NIL Val) )

The '(catch NIL' is still needed though.


'quit' is similar to 'throw'. It throws an error message instead of a tag, and
is triggered internally also when an error occurs, which then can be caught with
'(catch '("Message 1" "Message 2") ...



> Then there's the conditional exits in "for", "do" and "loop" which presents
> a real problem if you wish to terminate the loop from within a sub-clause:
> 
> (for X (1 2 3 4 5)
>   (let Y (mumble-mumble X)
>  (NIL Y (println "this doesn't work"

Yes. As also pointed out by Bruno, the 'T' and 'NIL' exit clauses must be on the
top level of the body. Usually code can be rearranged this way. If not,
catch/throw can be used here too.


> I'm also a pathological meta-programmer, and the lack of macros doesn't
> bother me as much as I thought it would. However, one thing I miss from
> other lisps is a way of expanding macros. How would I go on about doing that
> in PicoLisp?

For one thing, there are read-macros which are expanded at read-time.

Then, there is - also pointed out by Bruno - 'fill' and 'macro' which may
be used to build and execute expressions at runtime. 'macro' is rather seldom
used, as it introduces quite some overhead in an interpreted system.

The way to go for meta-programming is to use FEXPRs. Examples are many in the
PicoLisp package itself, or at https://software-lab.de/doc/faq.html#macros or
http://rosettacode.org/wiki/Extend_your_language#PicoLisp

—Alex

-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe