freenode/lisp - IRC Chatlog
Search
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?
23:58:17
krwq
hello, what was that website with current recommendations for libraries? specifically looking for something which would automatically replicate selected objects to the database and restore on start
0:02:14
flavio81
i'm very new to the CL ecosystem to recommend libraries, but two more or less recent ORMs are:
0:02:41
krwq
i just want to i.e. serialize list of some object to a database so that i can i.e. do (def-permanent-var *foo* (first-time-initialize)) and it would always save current state on change and restore same values when i restart my lisp - i never did much with databases
0:03:22
flavio81
with an ORM what you have is objects that have a correspondence with a table on a database, and you can save and load these objects to/from the database
0:03:41
flavio81
but it seems that what you want is to be able to save ANY object. That is "serialization"
0:04:21
flavio81
note that if you want to be able to save ANY object then what you want is a library for serialization, not an ORM
0:04:42
flavio81
a serialization library turns that object into binary (or text) form that then can be stored in a file, a table column, etc
0:04:56
krwq
flavio81: shouldn't there be genreic implementation and i could write my method to help it serialize to db?
0:05:06
flavio81
while what an ORM does is to let you have an Object class that is more or less a mirror image of a database table
0:06:45
flavio81
with this you can create SQL with Lisp code. Then you can use this SQL to 'talk' directly to a database using a library like Postmodern:
0:21:53
krwq
im slightly confused with this connect-toplevel in cl-dbi/datfly/mito, are they interchaangable? i currently use version from datafly, can i replace that safely with mito:connect-toplevel? why are there 3 versions?
0:29:52
flavio81
but i don't understand the question, because mito is an ORM, and datafly is just a DB access library. they are different things
0:33:25
krwq
when i simply depend on datafly system do i need do anything special to make it work with cl-dbi or it autoregisters some keyword for connect-toplevel
0:34:23
flavio81
krwq: yes, but datafly is a traditional database access library (you use SQL to talk to the db), while mito is an ORM (Object-Relational Mapper)
0:37:52
krwq
the example has a keyword as a first argument, but i.e. how do i add my own implementation so it works with it? wrap everything?
4:46:00
krwq
i have a package which is a metapackage for my other packages, is there some easy way to make it such that I can use stuff from other packages before explicitly defining them before (i.e. i'd like to use a:foo in package b and b:bar in package a)