freenode/lisp - IRC Chatlog
Search
11:32:57
rk[ghost]
wahoo! my intuition was correct and i was able to break out a function of gnu readline as expecterd
12:26:47
phoe
rk[ghost]: quicklisp distros are changed once a month AFAIK. you're better off cloning the newest version from github and PRing to it in most cases.
12:28:10
phoe
(defun rl:clear-screen () (uiop:run-command #+windows "cls" #-windows "/usr/bin/clear"))
12:28:47
phoe
rk[ghost]: a quicklisp dist is basically a list of all offered systems along with their version.
12:29:26
phoe
(but I might be very wrong here, this description is based on 50% intuition 50% accidental overhearing)
12:33:02
Xach
quicklisp provides a set of libraries that build together, and they are updated on a server once per month. if you call the update function, it will fetch those updates to your computer. otherwise it never locally updates.
12:33:30
Xach
if you have a system in an asdf directory somewhere, it will always be loaded before a quicklisp-provided system is loaded
12:35:35
rk[ghost]
phoe: ha. however, i like the abstraction layer of having gnu readline, such that it only requires that gnu's readline is on a system and not various other x, y, or z userspace tools
12:50:16
phoe
quote is pretty unique to Lisp because it's only really useful in places where you can directly manipulate code as data.
12:51:18
beach
Murii: It is similar to the rule in natural languages such as English. So air is something you can breathe, but "air" is a one-syllable word. In the first case, air gets "evaluated" to mean the substance. In the second case, because it is quoted, it refers to the word itself.
13:48:26
Xach
i don't really understand it though. http://report.quicklisp.org/2017-06-16/failure-report/mcclim.html
13:54:57
Xach
slyrus: it's a slightly idiosyncratic indexing system, but it has never failed on mcclim before
13:56:43
slyrus
I added a new ASDF .asd file down in Backends/PostScript. I'm wondering if that's what messed things up. So... zapping your fasls and running (ql:register-local-projects) are the two things that come to mind.
14:35:47
pjb
Murii: the important point wrt. quote, is that lisp programs are written using the format defined for lisp DATA.
14:36:34
pjb
Murii: actually, there's a (preliminary) syntax defined for lisp programs. Stuff like: label[subst;λ[[x;y;s];[null[s]->nil;atom[s]⟶[y=s->x;1->s];1->combine[subst[x;y;first[s]];subst[x;y;rest[s]]]]]]
14:37:23
pjb
Murii: in this syntax, there's no need for quote, since data is simply written with parentheses and uppercase, instead of brackets and lowercase: subst[(WATER;WINE;(MIX WATER AND WINE INTO (MIXED WATER AND WINE))];
14:39:28
pjb
Murii: but the thing is that: 1- there's a direct mapping of the lisp syntax to lisp data; 2- we can easily define an eval function that will take lisp data representing a lisp program, and interpret it; 3- a young student was impulsive and implemented this eval function in assembler before the syntax for lisp program was entirely finalized. The rest is history.
14:39:53
pjb
Murii: in this context, quote is used to indicate that its argument must not be interpreted as lisp code.
14:40:21
pjb
subst[(WATER;WINE;(MIX WATER AND WINE INTO (MIXED WATER AND WINE))]; translates to (subst (quote (water wine (mix water and wine into (mixed water and wine)))))
14:42:24
pjb
Murii: notice that this let an important invention (which existed entirely since the origin, but was embryonic) of macros: ie. functions transforming some lisp data into lisp code, embedded in the code, and called at compilation time.
14:44:24
pjb
Timeframe: AIM-8 specifies lisp and eval in Mars 1959; Russel implemented it in assembler 7090 from 1959-1960 (next version 1.5 in 1962); macros were invented in 1964. Until then, people still used the M-expressions (lisp code syntax) in papers; they only use S-expressions (lisp data syntax) on puched cards and listings. But once macros were introduced everybody flew with them and they forgot about M-expressions.
14:46:01
pjb
Murii: http://informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/aim-8/aim-8.html http://informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/m-expression/index.html
18:08:22
random_numbers
phoe: Read up the logs. 2017-06-16T08:05:02Z Touché. Though that's a fair bit lower-level than desirable.
19:52:29
faraco
question, as a beginner to functional programming paradigm, which language do you recommend to learn. Haskell or Lisp (cl, scheme, etc)?
19:53:29
faraco
I have some programmig background in Perl and C, and would love to expand my knowledge area to untouched territory in my career.
19:55:17
knusbaum
Both are good. Haskell is basically purely functional, while in CL you can program however you like. Both have good reading resources for beginners.
19:59:37
faraco
I just want to grasp my head with these functional stuff. I realized when writing code in another language, using functions like the popular map and reduce is really great and it really make the code concise. However, despite of my lack of experience in the usage area, doing Lisp might be a good idea since it seems much more expressive than the language I primarily use.
20:01:21
loke___
faraco: Lisp is multi-paradigm, which menas that you can mix imperative, functional, object-oriented etc. techniques in the same functions.
20:05:24
faraco
I see. Maybe I could read documentation somewhere to see why it is different, and why it is fun to you guys. Last question if you don't mind, if anything, what Lisp is really suited for and great at? I like to use a programming language for its out of the box features and design focus.
20:06:51
loke___
faraco: It's useful for a lot of things. Like I said, it's multi-paradigm, so there are really few things is doesn't do.
20:07:04
knusbaum
It's about as general-purpose as general-purpose can be. Since it has the features to alter and add to its own syntax and semantics, you can basically make it do anything.
21:26:28
rumbler31
question 2, I'm writing my own. I've ended up making a function that defines two inner functions with labels, one is supposed to be a closure (or mock closure) that calls the subject function with the initial varible arg and a supplied arg, which is used in the inner expand recusively
21:27:07
rumbler31
q2 is how can I tell/is it even possible for the compiler to make a recursive function defined with labels tail recursive?
21:28:15
rumbler31
like I want to say, call something like (expand 3 #'+ :count 5) and it will return a list of (3 6 9 12 15)
21:31:35
rumbler31
cheap trick if you want to supply an initial value just supply a nonempty list of one element
21:32:30
rumbler31
I can trace the toplevel but that doesn't show me that the inner function is tail recursive.
21:33:53
rumbler31
note, the function I posted doesn't take count as a keyword, that was just to disambiguate the idea of the function call's args
21:40:55
pjb
You don't need the rest argument. If the function needs additionnal information, you just pass a closure.
21:41:27
pjb
(Oh, unless you use it for an accumulator pattern; you can do that internally, but don't expose it on the public function signature).
21:43:36
White_Flame
(reverse (maplist (lambda (sublist) (reduce #'+ sublist)) (make-list 5 :initial-element 3)))
21:43:37
pjb
If you implemented your function with a loop or otherwise, you wouldn't have this accumulator anymore. It's an implementation detail.
21:44:33
White_Flame
presumably, this is reducing '(3 3 3 3 3) with #'+, collecting each intermediate result?
21:45:23
White_Flame
the reversed maplist is a little convoluted in order & reclaculation, but + is nice and transitive/commutative
21:46:21
rumbler31
White_Flame: yes but also why not #'* or some other function. I think pjb's mention of the accumulator pattern sounds like what I was trying to acheive, and I haven't walked through your example yet
21:46:52
White_Flame
maplist turns that list into (3) (3 3) (3 3 3) etc, which is then subsequently reduced with #'+
21:47:01
rumbler31
pjb: I don't know what you mean by passing a closure if the function needs more information. Rather, I know what you mean about making a closure but not how to apply it in this case
21:48:15
White_Flame
but yeah, an accumulator version makes a ton more sense, especially when efficiency or side effects are in the picture
21:48:59
pjb
rumbler31: for example, if you want to call the function + with N and each element of a list, you don't have a mapcar function that takes as argument N like: (let ((N 3)) (mapcar* (function +) N list)) ; instead, mapcar takes a closure: (let ((N 3)) (mapcar (lambda (x) (+ N x)) list))
21:51:06
rumbler31
pjb: I was intending for the second example in your sentence, did I not do that? With the rest param I leaked out to the user that you can supply an initial value, but I don't see how to make a closure to supply such
21:51:19
White_Flame
I don't know what you want un-reduce for, but it would seem that it also might want a separate starting value, in addition to the parameter given to the accumulator function
21:53:59
pjb
Then I realized you had an accumulator pattern, and I said that it's a big no-no to leak it from high level user-facing functions.
21:55:14
pjb
Notice that some CL function expose such a low-level parameter, eg. nreconc or revappend. Those are low-level functions used to implement eg. nreverse or reverse. But for a function such as reverse, it would be very bad to have an &optional accumulator!
21:56:36
White_Flame
is there a starting value, or is the 3 included in the list of numbers to be accumulated?
21:57:51
rumbler31
pjb: so you mean that if I am writing something that intends to accumulate values in a list and return that to the user, I shouldn't expose the "destination" list as an input to my function that does such?
21:58:17
rumbler31
like a recuse and recurse-inner, where inner takes the &rest param and the recurse doesn't? is that what you mean?