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

/prog/ challenge

Name: Anonymous 2014-07-16 18:35

Write a macro that, given a term of code, transforms all the calls to the function FOO in that term, and only those calls, into calls to function BAR with the same arguments.
Language: Common Lisp or Scheme.

Name: Anonymous 2014-07-16 18:50

Yep, it's our local Haskell faggot.

Name: Anonymous 2014-07-16 19:02

sed 's/FOO/BAR/'

Name: Anonymous 2014-07-16 19:24

>>2
So you can't.
>>3
Fail.

Name: not >>3 2014-07-16 21:13

Name: Anonymous 2014-07-16 22:29

Yeah, I left out the ``only'' part. Does lisp require whitespace?
sed 's/\(FOO /\(BAR /'

Name: Anonymous 2014-07-16 23:30

You want (funcall $'foo x) to change to (funcall #'bar x) as well? Or just (foo (foo x))
to (bar (bar x))?

Name: Anonymous 2014-07-16 23:39

Forget it, it's halting-complete.

Name: Anonymous 2014-07-16 23:40

Done.

(defun replace-foo-with-bar (expression)
(cond ((atom expression) expression)
((eq (car expression) 'foo)
(cons 'bar (replace-foo-with-bar* (cdr expression))))
((and (eq (car expression) 'funcall)
(or (eq (cadr expression) 'foo)
(equalp (cadr expression) '(function foo))))
(append '(funcall (function bar))
(replace-foo-with-bar* (cddr expression))))
(t (replace-foo-with-bar* expression))))

(defun replace-foo-with-bar* (expression)
(cond ((atom expression) expression)
((consp (car expression))
(cons (replace-foo-with-bar (car expression))
(replace-foo-with-bar* (cdr expression))))
(t (cons (car expression) (replace-foo-with-bar* (cdr expression))))))

Name: Anonymous 2014-07-16 23:44

Oh yeah you wanted a macro:

(defmacro qux (expression) (replace-foo-with-bar expression))

Name: Anonymous 2014-07-17 2:02

>>3,5,6
Lisp ``code'' is *never* text. By transforming text, you are accomplishing nothing.

Name: Anonymous 2014-07-17 2:08

>>11
never is not a global variable, why are you giving it earmuffs?

Name: Anonymous 2014-07-17 2:09

>>12
earmuffs
(I (don't appreciate ((this)))).

Name: Anonymous 2014-07-17 2:16

What is the relation of code, data, and text? What is the true way?

Name: Anonymous 2014-07-17 2:26

>>13
You are not ready for satori, young one.

>>14
Sex-pressions.

Name: Anonymous 2014-07-17 8:48

>>14

One of the very first lessons of the wizard book is that data is a type of abstract being that inhabits the computer (programs are another). Indeed programs are a kind of data which is executable by some other program. An executing program is called a process.

A Lisp program is a collection of Lisp objects, which are data. Sometimes a Lisp program is called "Lisp code".

The syntax (or structure) of a Lisp program is defined in terms of Lisp objects.

Text can be read by some program (possibly a Lisp program) which generates Lisp objects during the time it is reading that text. Conventionally, a program that reads text and generates Lisp objects is called a Lisp reader.

Lisp objects that are read in by a Lisp reader may also be Lisp programs.

One family of textual syntaxes Lisp readers usually understand are called "S-expressions". However there are others e.g. "M-expressions", "Sweet expressions" etc.

I hope this answers your questions.

Name: Anonymous 2014-07-17 9:23

>>16
As a lisp weenie, I never had to think of any of that abstract bullshit.

Name: Anonymous 2014-07-17 12:13

To lisp weenies, lisp is just a language with a hackable syntax.

Name: Anonymous 2014-07-17 13:08

>>18
Hax my anus

Name: Anonymous 2014-07-17 13:50

>>9
))))))
Stopped reading there

Name: Anonymous 2014-07-17 15:39

>>9
Aren't you a genius! Now try running this on

(let ((foo 1))
(+ 3 foo))

Name: Anonymous 2014-07-17 16:51

Why is
(qux `(let ((foo 1)) (+ 3 foo)))

different from

(defparameter *anus `(let ((foo 1)) (+ 3 foo)))

(qux *anus)

?

Lisp is like an ultimate manifestation of referential opaqueness and shittiness.

Name: Anonymous 2014-07-17 18:49

>>22
compile-time versus runtime you shitlord

Name: Shitlord 2014-07-17 19:20

>>23
Oh, OK. The challenge from the original post remains unsolved, though. Seems that s-exps are unsuitable for even the simplest codewalking.

Name: Anonymous 2014-07-17 19:22

You need to macroexpand, then replace, ignoring branches in which the variable becomes bound (via lambda or let). Where did all the good posters from 2005-2008 go? :(

Name: Anonymous 2014-07-17 19:41

>>24
sexper is fine for code walking. But what you want is a proof that *anus is never changed from its constant value, which entails much more than just code walking alone.

Name: Anonymous 2014-07-17 19:43

>>25
That is not a solution, because it not only replaces calls to FOO in the original term, but also in the expansions of other macros. E.g. if there exists the macro

(defmacro zoo (k) (foo k))

and our code term contains the s-exp

(zoo k)

then your erroneous solution will modify what (zoo k) will expand into, which is a malign side effect. Anything that is not a call to FOO must be untouched.

Name: Anonymous 2014-07-17 19:49

>>26
Alright, s-exps are unsuitable for even the simplest intelligent codewalking. Which is a necessary condition for writing useful code transforms.

Transforming untagged nodes and hoping that the result will be correct runnable code is like putting grenades in your barbecue and hoping that no one gets hurt.

Name: Anonymous 2014-07-17 20:58

>>28
Haskell is shit.

Name: Anonymous 2014-07-18 0:34

>>27
>>25 is correct. (mac (zoo k)) should be equivalent to (mac (foo k))

Name: Anonymous 2014-07-18 2:53

>>1
(defmacro foo->bar (&body body)
`(macrolet ((foo (&rest rest)
`(bar ,@rest)))
,@body))

Not sure why this is considered hard.

Name: Anonymous 2014-07-18 2:55

>>31
sorry, forgot tags
(defmacro foo->bar (&body body)
`(macrolet ((foo (&rest rest)
`(bar ,@rest)))
,@body))

Name: Anonymous 2014-07-18 3:08

>>25
Where did all the good posters from 2005-2008 go? :(
Shalom!

Name: Anonymous 2014-07-18 9:44

>>21
How embarassing.

>>32
Doesn't handle (function foo).

Name: Anonymous 2014-07-18 9:45

i.e. (funcall #'foo ...)

Name: Anonymous 2014-07-18 10:00

>>34
I've given it some thought and I don't believe that a macro is the correct tool to "replace" all function calls of foo to bar. It's not even clear what that means, unless you talk about function pointers. Even though >>32's example can be modified to handle the FUNCALL case, there's more things one can come up with to screw with the macro:

; to demonstrate:
(defun myfuncall ...)
(myfuncall #'foo ...)


Therefore, if anything, the solution used by >>32 is just fine. What >>9 wrote is also fine, only that it has to be used on the macroexpanded AST. Seriously, >>1 trolled us all by posting an ill-imposed problem.

Name: Anonymous 2014-07-18 10:06

>>36
Perhaps the lisp reader must be modified for this problem to be solved. Or whatever mechanism is that looks for the function tag in a symbol. However, I think this solution can not be applied locally. All in all, if >>1 can restate the problem considering the objections raised thusfar, I'll solve it.

Name: Anonymous 2014-07-18 10:36

>>36

I am >>9.

As it is, my program would not produce correct output on all fully macroexpanded expressions, because I am not handling all relevant special forms (do, let, tagbody etc.).

Of course, a program which does the requested replacement correctly for all of Common Lisp's 25 special operators as enumerated in section 3.1.2.1.2.1 of the Hyperspec could be written.

Interestingly, and enlighteningly, that program would be a new Lisp evaluator, and would define a new Lisp language.

Name: Anonymous 2014-07-18 10:45

>>36
I don't think your demonstrated case counts. It doesn't matter that, after transformation, the form calls a function that calls foo, just as long as foo isn't called directly.

Name: Anonymous 2014-07-18 10:51

>>39
and what does it mean for foo to be called directly? I think you haven't explained this one.

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