Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-4041-

newLISP the true champion of homoiconicity

Name: Anonymous 2012-11-10 10:11

Can your Lisp do this, /prog/?

(define (plus-minus a b)
  (begin
    (setf (nth '(1 2 0) plus-minus) (if (= (nth '(1 2 0) plus-minus) -) + -))
    (+ a b)))

(plus-minus 10 2)
8
(plus-minus 10 2)
12


newLISP treats code literally as data unlike Common Lisp or Scheme.

Name: Anonymous 2012-11-10 10:13

Now let's see how useful that is

Name: Anonymous 2012-11-10 10:17

Only the most unimaginative members of the herd can murmur Now let's see how useful that is

Name: Anonymous 2012-11-10 10:20

>>3
You have no better answer? Then I have no reason to believe it is useful.

Name: Anonymous 2012-11-10 10:23

>>1
THIS IMPURITY MUST BE PURGED!

Name: Anonymous 2012-11-10 10:45

Can you use a more interesting example? I could just do this if I wanted a oscillating function:

(let (p) #'(lambda () (progn (setf p (null p)) (if p #'+ #'-))))

Name: Anonymous 2012-11-10 13:51

>>6
Thats ugly as fuck.

Name: Anonymous 2012-11-10 14:19

>>7
And how is that at all dissimilar to the very concept of impure functions?

Name: Anonymous 2012-11-10 18:49

>>2,6

This is arbitrary code manipulation at the syntax level at run time. Consider an algebraic profiling optimizer.

Name: Anonymous 2012-11-10 19:09

>>4
I agree with you. I also have no imagination and cannot fathom any practical use for this.

Name: >>6 2012-11-10 19:18

>>9
Don't worry, I like it. A more interesting example is what I would have wanted.

Name: Anonymous 2012-11-10 19:21

some of the stack based languages have a similar abstraction of functions being flat arrays of constants. But it isn't parsed so it isn't as easy to use well.

Name: >>12 2012-11-10 19:22

err, not really an abstraction. Just a level of accessibility normally not granted.

Name: Anonymous 2012-11-10 20:37

I wish to be achieve macro satori, what must I read?

Name: Anonymous 2012-11-10 20:47

>>14
There isn't that much to them. Just use them a few times and then you will feel the satori building within you, just waiting to abstract and factor enterprise design patterns away into self implemented language features. It doesn't need to be a lisp either, but it should have a comparable macro system.

Name: Anonymous 2012-11-10 20:57

http://cl-cookbook.sourceforge.net/macros.html
(defmacro setq2 (v1 v2 e)
   (let ((e1 (comtran e)))
      (list 'progn (list 'setq v1 e1) (list 'setq v2 e1))))

(defun comtran (exp) ...) ;; Right!


Wait, what the fuck?  Macro setq2 just uses procedure comtran without any issues?  But comtran isn't even defined yet!  What if someone does something evil/stupid like (let ((comtran evil-procedure)) (setq2 x y z))?  What if comtran has an instance of setq2 in it?  Is it just me, or macroexpansion-time stuff should live in its own namespace?

Name: Anonymous 2012-11-10 21:54

Name: Anonymous 2012-11-10 22:14

>>16
Evaluation time of macros is a bit confusing. Don't worry, you'll get it soon.

Name: Anonymous 2012-11-10 23:21

Name: Anonymous 2012-11-11 7:12

Name: Anonymous 2012-11-11 10:51

>>20
Terrible!

Name: Anonymous 2012-11-11 11:43

>>22
HOLY FUCK!!!!!!!!!!!!!!
dubs

Name: Anonymous 2012-11-11 12:22

>>18
No, it's very confusing. :/

Name: Anonymous 2012-11-11 13:02

Name: Anonymous 2012-11-11 15:35

>>24
That still doesn't enlighten me as to how macros are supposed to be able to use regular functions (not defined in some sort of macrospace).

Name: Anonymous 2012-11-11 15:43

>>25

If mf is a function and m is a macro defined as:

(defmacro m (&rest args)
  (apply mf args))

Then the following are equivalent:


(m 2 3 4)
(eval (mf 2 3 4))



(m (* 5 6 (/ 7 8)) (eat apple))
(eval (mf '(* 5 6 (/ 7 8)) '(eat apple)))

Name: >>26 2012-11-11 15:49

In other words, mf is a function that takes a syntax tree as an argument and produces another syntax tree for evaluation.

Name: Anonymous 2012-11-11 16:27

>>26
Yes, but mf is a regular function!  What if yo do something like

(defun mf (...) ...)

(let ((mf something-else))
  (defmacro m (&rest args)
    (apply mf args)))

Name: >>28 2012-11-11 16:27

*you

Name: Anonymous 2012-11-11 16:32

>>28
In that case the macro m has lexical scope, and it uses the mf function defined in the let statement for its code transformer. It is powerful to let any user defined lisp function to assist your macro. And we are creeping up on first class macros, but we haven't gotten there yet.

Name: Anonymous 2012-11-11 16:35

]=> (define plus-minus
  (let ((plus? #t))
    (lambda (a b)
      (set! plus? (not plus?))
      ((if plus? + -) a b))))
plus-minus
]=> (plus-minus 10 2)
8
]=> (plus-minus 10 2)
12

Name: Anonymous 2012-11-11 16:44

(eval (macro-function ...))

Name: Anonymous 2012-11-11 17:27

>>30
Wow, I can't believe that actually works.  I'm going to go ahead and try to write a macroexpand function in terms of eval and apply.

Name: Anonymous 2012-11-11 17:40

>>33
Wow, I can't believe I was alive to witness those awesome dubs.

Name: Anonymous 2012-11-11 18:25

REPL MY ANUS

Name: Anonymous 2012-11-11 21:44

And we are creeping up on first class macros, but we haven't gotten there yet.
Why not just use Factor? It's had first class macros for years.

Name: Anonymous 2012-11-12 1:06

Explicit macros are a leaky abstraction.

There, I said it.

Name: Anonymous 2012-11-12 1:44

>>37

Making them explicit helps with efficiency in the implementation. To maintain performance, they should all be expanded at compile time, and this would be hard if they weren't explicit. Not to mention a macro getting into a place where you only wanted a function would be a hard bug to figure out. But like all things that help performance, it must also cut down on expressive power and possibilities.

Name: Anonymous 2012-11-12 2:11

>>38
>>37 didn't say that the leakiness isn't justified.

Name: 33 2012-11-12 4:50

Little did I know that my endeavour would slowly drive me to madness.  Seriously, what the fuck.  I need some good references on macro magic, and maybe a hug or two.

Name: Anonymous 2012-11-12 7:28

Macros are a poor man's Fexprs.

http://en.wikipedia.org/wiki/Fexpr#Mainstream_use_and_deprecation

At the 1980 Conference on Lisp and Functional Programming, Kent Pitman presented a paper "Special Forms in Lisp" in which he discussed the advantages and disadvantages of macros and fexprs, and ultimately condemned fexprs. His central objection was that, in a Lisp dialect that allows fexprs, static analysis cannot determine generally whether an operator represents an ordinary function or a fexpr — therefore, static analysis cannot determine whether or not the operands will be evaluated. In particular, the compiler cannot tell whether a subexpression can be safely optimized, since the subexpression might be treated as unevaluated data at run-time.

tl;dr version:

Le jew PITMAN condemns fexprs because he cannot his way into static analysis. But being Lisp is all about direct manipulation of the AST, who the fuck cares about Le static analysis.

Name: Anonymous 2012-11-12 7:43

>>41
Lispers have historically strived to make their Jewish Kabbalah magickz both efficient and versatile, and both the intent and the knowledge required to do so is what has set them apart from the scripting languages ``BDFL''s who designed pretty languages with shit semantics and performance.

Name: >>40 2012-11-12 16:17

My quest for macro satori has finally made me insane.  I no longer distinguish between reality and imagination, or between compile-time and run-time.

Name: Anonymous 2012-11-12 19:44

>>42
Should we believe that, le goog programmateurs will come with über-engineered v8.

Name: Anonymous 2012-11-12 22:50

>>43
doing something at compile time is just an optimization of doing it at run time. Both yield the same behavior so they cannot be distinguished.

Name: 2012-11-13 3:35

Name: Anonymous 2012-11-13 11:48

>>45
doing something at compile time is just an optimization of doing it at run time. Both yield the same behavior so they cannot be distinguished.
Please give me a reference with lots and lots of Lisp macro examples with as many interactions between compile- and run-time as possible.

Name: Anonymous 2012-11-13 12:24

>>47

Well, I've been thinking about your dilemma, so I've put together a test.


mac.lisp:
(defmacro confusing (a)
  (print (list "is this compile or run time? " a))
  a)


(defun client-fun (a b c)
  (+ (confusing a) (confusing b) (confusing c)))



[1]> (load 'mac.lisp)
;; Loading file mac.lisp ...
("is this compile or run time? " A)
("is this compile or run time? " B)
("is this compile or run time? " C)
;; Loaded file mac.lisp
T
[2]> (client-fun 1 2 3)
6
[3]>




Looks like compile time in this case. If the macro expansion function had no side effects, then the compile time macro expansion could be seen as constant folding, since all macros are invoked on constant ast literals typed into the program. But in this case the macro causes a side effect, so its evaluation time is significant. When this will happen really depends on the lisp that you are using. First class macro expansions must happen at run time.

Name: Anonymous 2012-11-13 13:02

>>1
Dynamic scoping is shit.
Lexical scoping is superior.

Name: Anonymous 2012-11-13 13:14

if it's not sweet.js, it's wrong

Name: Anonymous 2012-11-13 13:43

/polecat kebabs/

Name: Anonymous 2012-11-13 13:56

>>49
You can implement lexical scoping in dynamically scoped Lisp. The reverse, however, is not possible.

Name: Anonymous 2012-11-13 14:00

>>52
Dynamically scoped lisp (or, for that matter, any language) sucks dicks at optimization.

Name: Anonymous 2012-11-13 14:14

>>55
nice dubs bro

Name: Anonymous 2012-11-13 14:21

>>53
Depends on the implementation. And what ``optimization'' are we talking about here?

Name: Anonymous 2012-11-13 15:03

>>52
Implement lexical-lambda and lexical-let, then.

Name: Anonymous 2012-11-13 23:21

Name: Anonymous 2012-11-14 0:19

>>1-57
lambda fucking nerdulus.

Name: Anonymous 2012-11-14 5:05

>>56
lexical-let can be implemented using lexical-lambda.
lexical-lambda can be implemented as a tuple together with a reference to the parent activation frame in which the lambda is instantiated.

dynamic scope can be implemented as a hash table of stacks or a stack of hash tables.

Name: Anonymous 2012-11-14 9:14

>>59
reference to the parent activation frame in which the lambda is instantiated.
And how are you going to get that?

Name: Anonymous 2012-11-14 9:55

>>60
he just told you how.. isn't it obvious?

Name: Anonymous 2012-11-14 13:47

>>61
That needs interpreter/compiler hacks, the same way dynamic-scoping-in-lexical-scoped-language needs hacks.

Name: Anonymous 2012-11-15 2:23

>>62
It's lexical scope is more predicable than dynamic scoping. The relationship to the parents is fixed at compile time because the function definitions cannot move around. They have a nested grouping that is fixed and defined for the source file. With dynamic scoping, the parent relationship is dynamic and determined by the state of the function all stack. So the program must be prepared for many different cases when looking up the value of a variable in a parent frame.

Don't change these.
Name: Email:
Entire Thread Thread List