[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.lisp

Future of lisp or evolution

SergioBG BG

4/28/2015 4:39:00 PM

Hi , one question out of curiosity.

I can see javascript , C++ , python etc are languages in evolution ,is lisp in this stage ?
Sorry if question is ridiculous.
4 Answers

Pascal J. Bourguignon

4/28/2015 5:01:00 PM

0

SergioBG BG <sergiobgar@gmail.com> writes:

> Hi , one question out of curiosity.
>
> I can see javascript , C++ , python etc are languages in evolution ,is
> lisp in this stage ?

Yes, and much more than those languages.

Indeed, with those languages, you, the simple programmer, is pending on
a comitee or some lunatic^W "benevolent" dictator to come up with new
ideas for language changes, and you get updates to the standard only
each few years, then you have to wait for the compiler vendors to update
their compilers, and users to get the updated compilers, before you can
distribute code using the new features.

And what would you bet that the feature you'd want to see in those
languages will be included in the next release of the standard?


On the other hand, with Common Lisp, YOU, the mere programmer, can make
the language evolve as you wish, right now, immediately, instead of
wasting time on cll. No need to bribe a standard comiteed, no need to
buy a beer to some dictator. YOU get to make the language what you want
it to be!

How can you do so? Just like the CL standard comitee did: by defining
the packages, the reader macros, and the macros you need to define your
own language!


The Common Lisp reader really knows to scan only symbols, integers and
floating point numbers. All the rest of the syntax is implemented with
reader macros, that YOU, the mere programmer, could write yourself, or
could change or remove as you wish.

The Common Lisp standard contains 25 special operators, 88 macros and
636 functions (plus some more setf-function that I didn't count,
variables, constant variables, types, etc).

While some of the functions in the standard must be implemented as
"primitive" functions because implementing them only with the special
operators would raise the metalinguistical level, the set of primitive
functions is not defined, but is left up to the implementation.

Similarly the standard explicitely allows implementations to implement
any CL operators (special operators, macros or functions) as special
operators, as long as the implementation provides macros for the
standard macros, and functions for the standard functions. What this
means, is that the standard doesn't impose the set of special operators
as a "primitive" set either.

Nonetheless, the point is that most of the CL language is actually
defined as a set of 88 macros written just as YOU, the mere programmer,
can write macros, and you could very well define your own set of macros
and functions, to define your own language in your own package.


For example, some mere programmer like YOU, thought that the CL language
should evolve more toward scheme, and thus implemented his own "SCHEME"
package, in pseudo-scheme, such as now the language is scheme instead of
CL:

[pjb@kuiper :0.0 pseudo]$ clisp -ansi -norc -q
[1]> (load"init.lisp")
;; Loading file init.lisp ...
;; Loaded file init.lisp
#P"/home/pjb/src-lisp/implementations/pseudo/init.lisp"
[2]> (scheme)
;; Loading file /home/pjb/src-lisp/implementations/pseudo/pseudo.lisp ...
;; â?¦
;; Loaded file /home/pjb/src-lisp/implementations/pseudo/pseudo.lisp
This is Pseudoscheme 2.12.

scheme[3]> ((if (= 1 2) car cdr) (cons 1 2))
2
scheme[4]> (quit)
Leaving Pseudoscheme.

[5]> (quit)
[pjb@kuiper :0.0 pseudo]$


For another example, have a look at:
https://common-lisp.net/projec...


But you just have to read any CL code, and you will see how mere
programmers like YOU redefine and make the language evolve everyday,
without needing the approval of some father-figure.



> Sorry if question is ridiculous.

I'll let you ponder this.

--
__Pascal Bourguignon__ http://www.informat...
â??The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.� -- Carl Bass CEO Autodesk

Kaz Kylheku

4/28/2015 6:44:00 PM

0

On 2015-04-28, SergioBG BG <sergiobgar@gmail.com> wrote:
> Hi , one question out of curiosity.
>
> I can see javascript , C++ , python etc are languages in evolution ,is lisp
> in this stage ?

More language evolution happens in a typical project written in the Lisp
language, than what happens in Python, Javascript or C++.

Javascript, Python and C++ users have to wait for the next release of the
compiler or interpreter.

Moreover, the development is done behind closed doors, by people who don't
necessarily care what the users want or need. The ISO C++ process is
destroying the C++ language with garbage features, for instance.

Lisp users just write the language features that they actually need, here and
now in their project, or borrow them from other people.
Language features are just library features. You can patch them easily
if you need to, remove stuff you don't want, change them to suit your project
and the like.

On top of that, people are experimenting with new dialects like Clojure and
Racket.

I'm innovating in small ways in a dialect of Lisp ebmedded into a data
munging tool called TXR.

Just this week I made a release in which a new Lisp macro is featured, called
mlet ("magic let" or "mutual let"), which I invented. It goes one step beyond
Scheme's letrec.

Fristly, under mlet, all variable initializations are delayed until the "first
use" of a variable:

Example:

(mlet ((a (progn (prinl "a inited") 1))
(b (progn (prinl "b inited") 2))
(c (progn (prinl "c inited") 3)))
(list c b))

Here only c and b are accessed, so only those variables are initialized.
Moreover, they are accessed in that order -- c, then b -- and so
we will see

"c inited"
"b inited"

and the result will be the list (3 2). We do not see "a inited".

Secondly, under mlet, all the init forms have all the variables in scope.
Therefore, this is possible:

;; Dependent calculations in arbitrary order
(mlet ((x (+ y 3))
(z (+ x 1))
(y 4))
(+ z 4)) --> 12

The initialization of x looks forward to the variable y. z looks backward
to x. Everything is worked out.

Lastly, if a lazy data structure constructor is used (like the lcons macro
in TXR Lisp to make a lazy cons), mlet allows for a cyclic reference:

(mlet ((circ-list (lcons 1 circ-list)))
circ-list) -> (1 1 1 1 1 ....) ;; circular list, not lazy-infinite

How this works is that the variable circ-list is referenced for the
first time in the body and so it is initialized at that time.
The (lcons ...) expression is evaluated. Now lcons is a macro which
delays the evaluation of its arguments, therefore the circ-list
argument isn't evaluated---which is a good thihg, because we haven't
finished initializing the variable. So without evaluating circ-list,
lcons yields a lazy cons cell, which then becomes the value of circ-list.
When the lazy cons cell's fields later materialize, its cdr field
will refer back to itself, creating a circular list.

Ordinary eager circularity is erroneous and is detected:

Firstly:

$ txr -p '(mlet ((x (+ 1 y)) (y (+ 2 x))))'

No problem here: why? Because x and y are not referenced in the body.
Let's add a reference to x:

$ txr -p '(mlet ((x (+ 1 y)) (y (+ 2 x))) x)'
txr: unhandled exception of type eval-error:
txr: message: (string:1) force: recursion forcing delayed form (+ 1 y) (string:1)

mlet is a small example of actual language evolution: it's code which
executes, today. Not some fucking ISO standard that will be coming
to everyone's compiler except for yours in 2017.

I didn't discuss it with anyone. I designed it, coded it and pushed it out
the door.

If someone wants it in their Lisp dialect, they can read my documentation,
study the code, if necessary and implement it in a compatible way.
To do that, they won't have to hack the Lisp implementation itself.

Good luck getting the equivalent of mlet into Python, Javascript or
(LOL) C++.

SergioBG BG

4/28/2015 7:18:00 PM

0

El martes, 28 de abril de 2015, 20:43:55 (UTC+2), Kaz Kylheku escribió:
> On 2015-04-28, SergioBG BG <sergiobgar@gmail.com> wrote:
> > Hi , one question out of curiosity.
> >
> > I can see javascript , C++ , python etc are languages in evolution ,is lisp
> > in this stage ?
>
> More language evolution happens in a typical project written in the Lisp
> language, than what happens in Python, Javascript or C++.
>
> Javascript, Python and C++ users have to wait for the next release of the
> compiler or interpreter.
>
> Moreover, the development is done behind closed doors, by people who don't
> necessarily care what the users want or need. The ISO C++ process is
> destroying the C++ language with garbage features, for instance.
>
> Lisp users just write the language features that they actually need, here and
> now in their project, or borrow them from other people.
> Language features are just library features. You can patch them easily
> if you need to, remove stuff you don't want, change them to suit your project
> and the like.
>
> On top of that, people are experimenting with new dialects like Clojure and
> Racket.
>
> I'm innovating in small ways in a dialect of Lisp ebmedded into a data
> munging tool called TXR.
>
> Just this week I made a release in which a new Lisp macro is featured, called
> mlet ("magic let" or "mutual let"), which I invented. It goes one step beyond
> Scheme's letrec.
>
> Fristly, under mlet, all variable initializations are delayed until the "first
> use" of a variable:
>
> Example:
>
> (mlet ((a (progn (prinl "a inited") 1))
> (b (progn (prinl "b inited") 2))
> (c (progn (prinl "c inited") 3)))
> (list c b))
>
> Here only c and b are accessed, so only those variables are initialized.
> Moreover, they are accessed in that order -- c, then b -- and so
> we will see
>
> "c inited"
> "b inited"
>
> and the result will be the list (3 2). We do not see "a inited".
>
> Secondly, under mlet, all the init forms have all the variables in scope.
> Therefore, this is possible:
>
> ;; Dependent calculations in arbitrary order
> (mlet ((x (+ y 3))
> (z (+ x 1))
> (y 4))
> (+ z 4)) --> 12
>
> The initialization of x looks forward to the variable y. z looks backward
> to x. Everything is worked out.
>
> Lastly, if a lazy data structure constructor is used (like the lcons macro
> in TXR Lisp to make a lazy cons), mlet allows for a cyclic reference:
>
> (mlet ((circ-list (lcons 1 circ-list)))
> circ-list) -> (1 1 1 1 1 ....) ;; circular list, not lazy-infinite
>
> How this works is that the variable circ-list is referenced for the
> first time in the body and so it is initialized at that time.
> The (lcons ...) expression is evaluated. Now lcons is a macro which
> delays the evaluation of its arguments, therefore the circ-list
> argument isn't evaluated---which is a good thihg, because we haven't
> finished initializing the variable. So without evaluating circ-list,
> lcons yields a lazy cons cell, which then becomes the value of circ-list.
> When the lazy cons cell's fields later materialize, its cdr field
> will refer back to itself, creating a circular list.
>
> Ordinary eager circularity is erroneous and is detected:
>
> Firstly:
>
> $ txr -p '(mlet ((x (+ 1 y)) (y (+ 2 x))))'
>
> No problem here: why? Because x and y are not referenced in the body.
> Let's add a reference to x:
>
> $ txr -p '(mlet ((x (+ 1 y)) (y (+ 2 x))) x)'
> txr: unhandled exception of type eval-error:
> txr: message: (string:1) force: recursion forcing delayed form (+ 1 y) (string:1)
>
> mlet is a small example of actual language evolution: it's code which
> executes, today. Not some fucking ISO standard that will be coming
> to everyone's compiler except for yours in 2017.
>
> I didn't discuss it with anyone. I designed it, coded it and pushed it out
> the door.
>
> If someone wants it in their Lisp dialect, they can read my documentation,
> study the code, if necessary and implement it in a compatible way.
> To do that, they won't have to hack the Lisp implementation itself.
>
> Good luck getting the equivalent of mlet into Python, Javascript or
> (LOL) C++.
Aja I can see what you say , lisp is modifiable as you need ., but with macros?

Kaz Kylheku

4/28/2015 7:33:00 PM

0

On 2015-04-28, SergioBG BG <sergiobgar@gmail.com> wrote:
> El martes, 28 de abril de 2015, 20:43:55 (UTC+2), Kaz Kylheku escribió:
>> On 2015-04-28, SergioBG BG <sergiobgar@gmail.com> wrote:
>> > Hi , one question out of curiosity.
>> >
>> > I can see javascript , C++ , python etc are languages in evolution ,is lisp
>> > in this stage ?
>>
>> More language evolution happens in a typical project written in the Lisp
>> language, than what happens in Python, Javascript or C++.
>>
>> Javascript, Python and C++ users have to wait for the next release of the
>> compiler or interpreter.
>>
>> Moreover, the development is done behind closed doors, by people who don't
>> necessarily care what the users want or need. The ISO C++ process is
>> destroying the C++ language with garbage features, for instance.
>>
>> Lisp users just write the language features that they actually need, here and
>> now in their project, or borrow them from other people.
>> Language features are just library features. You can patch them easily
>> if you need to, remove stuff you don't want, change them to suit your project
>> and the like.
>>
>> On top of that, people are experimenting with new dialects like Clojure and
>> Racket.
>>
>> I'm innovating in small ways in a dialect of Lisp ebmedded into a data
>> munging tool called TXR.
>>
>> Just this week I made a release in which a new Lisp macro is featured, called
>> mlet ("magic let" or "mutual let"), which I invented. It goes one step beyond
>> Scheme's letrec.
>>
>> Fristly, under mlet, all variable initializations are delayed until the "first
>> use" of a variable:
>>
>> Example:
>>
>> (mlet ((a (progn (prinl "a inited") 1))
>> (b (progn (prinl "b inited") 2))
>> (c (progn (prinl "c inited") 3)))
>> (list c b))
>>
>> Here only c and b are accessed, so only those variables are initialized.
>> Moreover, they are accessed in that order -- c, then b -- and so
>> we will see
>>
>> "c inited"
>> "b inited"
>>
>> and the result will be the list (3 2). We do not see "a inited".
>>
>> Secondly, under mlet, all the init forms have all the variables in scope.
>> Therefore, this is possible:
>>
>> ;; Dependent calculations in arbitrary order
>> (mlet ((x (+ y 3))
>> (z (+ x 1))
>> (y 4))
>> (+ z 4)) --> 12
>>
>> The initialization of x looks forward to the variable y. z looks backward
>> to x. Everything is worked out.
>>
>> Lastly, if a lazy data structure constructor is used (like the lcons macro
>> in TXR Lisp to make a lazy cons), mlet allows for a cyclic reference:
>>
>> (mlet ((circ-list (lcons 1 circ-list)))
>> circ-list) -> (1 1 1 1 1 ....) ;; circular list, not lazy-infinite
>>
>> How this works is that the variable circ-list is referenced for the
>> first time in the body and so it is initialized at that time.
>> The (lcons ...) expression is evaluated. Now lcons is a macro which
>> delays the evaluation of its arguments, therefore the circ-list
>> argument isn't evaluated---which is a good thihg, because we haven't
>> finished initializing the variable. So without evaluating circ-list,
>> lcons yields a lazy cons cell, which then becomes the value of circ-list.
>> When the lazy cons cell's fields later materialize, its cdr field
>> will refer back to itself, creating a circular list.
>>
>> Ordinary eager circularity is erroneous and is detected:
>>
>> Firstly:
>>
>> $ txr -p '(mlet ((x (+ 1 y)) (y (+ 2 x))))'
>>
>> No problem here: why? Because x and y are not referenced in the body.
>> Let's add a reference to x:
>>
>> $ txr -p '(mlet ((x (+ 1 y)) (y (+ 2 x))) x)'
>> txr: unhandled exception of type eval-error:
>> txr: message: (string:1) force: recursion forcing delayed form (+ 1 y) (string:1)
>>
>> mlet is a small example of actual language evolution: it's code which
>> executes, today. Not some fucking ISO standard that will be coming
>> to everyone's compiler except for yours in 2017.
>>
>> I didn't discuss it with anyone. I designed it, coded it and pushed it out
>> the door.
>>
>> If someone wants it in their Lisp dialect, they can read my documentation,
>> study the code, if necessary and implement it in a compatible way.
>> To do that, they won't have to hack the Lisp implementation itself.
>>
>> Good luck getting the equivalent of mlet into Python, Javascript or
>> (LOL) C++.
> Aja I can see what you say , lisp is modifiable as you need ., but with
> macros?

Macros is pretty much all that the "other guys" have also. What Lisp calls
a macro is a "syntax rule" in C++. The Lisp programmer can write that in Lisp,
whereas the C++ programmer has to unpack the sources to GNU C++, and
write a new rule in the Yacc grammar, plus additional code to bring
about the translation scheme for that piece of grammar.

Lis macros aren't like C preprocesor macros; they are like phrase structure
rules in a C compiler. For instance "while (expr) statement" is a kind of
macro in the C compiler. The parser recognizes it, and builds some
abstract syntax tree. This might then undergo "macro expansion" into
an tree which just uses if, goto and a pair of generated labels, corresponding
to the code.

Original: while (expr1) { if (expr2) break; expr3; }

Expansion: L0001: if (expr1) { if (expr2) goto L0002; expr3; goto L0001 }
L0002: ;

The compiler-generated labels are just like "gensyms" in Lisp.

Look, the LOOP feature of Lisp is a macro. It's obviously a mini-programming
language for loops, featuring clauses with a varied grammar:

(macroexpand '(loop for x in '(1 2 3) and for y = 1 then (1+ y)
collect (list x y)))

Lisp macros are (or can be) "bullet-proof", like statements in Python or C++.

Also, the word "syntax" in Lisp usually refers to structure of macros
and special operators, rather than to the raw text which features things like
hash marks and parentheses. (That is called "read syntax").