freenode/#lisp - IRC Chatlog

Search
9:29:11 MrTrump ** NICK Mitzelflick
9:49:59 abbe hi
9:51:14 abbe question about asdf/quicklisp: I have created my $project directory in $quicklisp/local-projects, and created two files: $quicklisp/local-projects/$project.asd and $quicklisp/local-projects/$project-tests.asd
9:52:11 XachX They are not in the project director?
9:52:21 abbe but when I do "(ql:quickload :$project)", it works, but when I do "(ql:quickload :$project-tests)", I get the error "System $project-tests not found"
9:52:27 abbe oh, sorry
9:52:33 abbe yes, they are in the $project directory
9:53:01 abbe so, $quicklisp/local-projects/$project/$project.asd, and $quicklisp/local-projects/$project/$project-tests.asd
9:53:26 XachX Did you create the test one some time after you loaded the main one once?
9:53:33 abbe yes
9:53:52 abbe do I need to purge some cache ?
9:54:04 XachX Then you have to help out a bit with ql:register-local-projects
9:54:36 XachX It goes by directory timestamps
9:54:41 abbe great, that works.
9:54:44 abbe thank you.
9:54:55 XachX No problem
9:55:21 myrkraverk Is there any publicly available DNS client stuff in CL, that I can use to write tests or play with my server?
9:55:41 myrkraverk I'd rather not have to play with that stuff in C, or GNU forbid, perl.
9:56:29 myrkraverk And if I'm implementing both the client and server, it's too easy to screw up some part of the protocol.
9:57:04 myrkraverk Oh, thanks.
9:57:19 abbe it's slow loadable atm
9:57:23 abbe you're welcome
10:31:12 malice Hey! What's the simplest way to get do..while loop?
10:35:50 easye malice: Use LOOP?
10:36:25 sjl__ ** NICK sjl
10:38:24 malice easye: actually yeah, I didn't know while works this way in loop :)
10:39:47 easye Good. Didn't know if you were part of the "LOOP isn't good Lisp" crowd.
10:46:34 easye I'll admit that there is a lot to criticize about LOOP (c.f. A.3.7. in <https://common-lisp.net/project/iterate/doc/Don_0027t-Loop-Iterate.html>) especially in how LOOP is essentially opaque to macrology, but it is so damn useful.
10:48:00 malice I agree. And I guess I'm too "fresh" lisper to argue with what's good Lisp and what's not
10:48:36 easye Then, simply relax, and enjoy the ride...
10:48:51 easye Criticism and disillusionment will come later.
10:49:56 malice One question though; I remember that when I was reading Cltl2, I've noticed something about extending LOOP macro(or is it just me?); however, I can't find resources that say how to do so. I know you can extend iterate, but how about LOOP?
10:50:51 easye Not as far as I know. That's one of the problems with LOOP in that there is no defined protocol for such extension.
10:51:19 easye Something may work in a given Lisp implementation, but it probably won't work in another.
10:51:59 malice Too bad. Thanks.
10:52:18 easye I'd be interested in figuring out where you read about extension. I can't recall such a passage (but that doesn't mean anything, as I am hardly an authority).
10:53:45 malice easye: I would like to know it myself. I was reading it long time ago, so I might be mistaken; it might have been other book, or I even might confuse LOOP with ITERATE, but I guess that I read something like "LOOP will probably be extendable, but we don't know how yet"
11:11:49 Poenikatu In the CL-CFFI-GTK tutorial, the example (example-button-box) compiles successfully, but fails when run with the error message "null-pointer in parse-g-param-spec". Has anyone got this to work?
11:29:54 malice Poenikatu: I can try it, did you get it from quicklisp?
11:30:16 Poenikatu Yes
11:43:53 malice Poenikatu:I get a compile-time errors, but not from example-button-box; after loading anyway, I get division by 0
11:44:12 malice And since I never tried using this, I can only tell you this much.
11:44:53 Poenikatu I've successfully tried all the examples upto the button box. Which example gave you compile time errors?
11:46:49 Poenikatu malice: The version I've got is cl-cffi-gtk-20141217-git (look for it in ~/quicklisp/dists/quicklisp/software)
11:54:26 malice Poenikatu: same here
11:55:35 malice Poenikatu: I just did C-c C-k in tutorial.lisp and got undefined function (setf gtk-label-set-label)m and duplicate definition for create-about-dialog, then "compilation failed".
11:55:47 malice So I ignored them and loaded fasl anyway, but you can see ther esults
11:57:07 Poenikatu malice: I've not tried compiling tutorial.lisp. I've been working through the tutorial, reading all the doc'n and trying out the examples. They all work upto the button box.
12:01:48 Poenikatu malice: Try (gtk-label-set-text)
12:03:17 Poenikatu malice: Hm, that function is in the API, but also doesn't work. Hm
12:12:06 malice Poenikatu: Yeah, I sometimes get the feel like people don't compile the code from the clean state when they release it
12:12:13 malice But you can't catch all the bugs, eh? ;)
12:16:57 haom hello, does anybody have some experience with CFFI?
12:17:00 malice Now I'm trying these one by one, these are cool
12:17:33 loke` haom: yes
12:17:36 loke` Lots of people
12:17:40 malice :)
12:18:03 haom i have the following problem: I'm trying to pass a lisp string as a C wide character string of the form L"abc".
12:18:28 loke` haom: Wide character strings are very losely defined in the C sped
12:18:33 loke` loosely
12:18:51 loke` haom: Thay are different on every compiler, so you have to be more precise in what you want to do.
12:18:59 haom the C function expects a pointer to a wchar_t, and I'm just doing cffi:foreign-string-alloc "abc".
12:19:14 haom but that crashes sbcl and sends me to the low-level debugger ldb.
12:20:03 haom so i dont know what foreign-string-alloc now allocates, a string of type "abc" or L"abc".
12:20:06 loke` haom: Yes, because a wide string is defined to be a secuence of wchar_t. That's all the C spec says. It says nothing about the size of wchar_t, nor what a wchar_t actually IS.
12:20:28 loke` On Windows, for example wchar_t is a 16-bit entity and a widestring is a UTF-16 sequence.
12:20:53 loke` On Linux, it's a 32-bit entity, and a widestring is (usually) a UTF-32 sequence.
12:21:26 loke` There are also cases where wchar_t is 32-bit but a widestring is still UTF-16. And then you have broken OS'es (older windows?) where a widestring is UCS-2
12:23:02 haom so do you have any idea how i could tell cffi to specifically allocate a wchar_t string?
12:23:20 loke` haom: Were you not listening to what I said?
12:24:45 haom i did, but i still dont know how to do what i want to?
12:25:14 loke` haom: I can tell you how to do it, if you tell me specifically what you want to do. Hell, you haven't even explain what operating system you use.
12:26:24 haom ok, i'm on a linux 64 bit, I'm trying to send from sbcl a string so a C-library function that expects a wide char string accepts it without crashing sbcl.
12:26:58 loke` haom: What API is this? Every single C API I've seen on Linux uses UTF-8 using plain char * strings.
12:27:17 loke` haom: wchar_t is a legacy thing that never even took off. So I'm surprised to see it being used.
12:28:57 Poenikatu malice: I'm looking at the file gtk.label.lisp and the C function gtk_label_set_text is explicitly mentioned
12:29:25 haom loke`: the C api is ncurses.
12:29:33 loke` haom: What API is this? This looks like some curses variation?
12:30:35 loke` haom: Yeah, don't use that
12:30:38 Poenikatu malice: The slot in a label widget is "label"
12:30:51 loke` haom: Just use the plain char * versions.
12:30:58 loke` And make sure you send UTF-8 to it.
12:31:44 haom loke`: well, it doesnt actually work with the plain char versions.
12:31:57 loke` haom: So basically encode your character to a UTF-8 string and print it with waddstr()
12:32:37 loke` Don't use plain chars. ThereUnicode really doesn't have much of a conect of "plain char" anyway. Even with widestrings you end up with "characters" that are multiple wchar_t long.
12:32:56 haom loke`: displaying strings works, but I'm trying to display single characters, and the setcchar + wchar_t is the official interface for this.
12:32:56 malice Poenikatu: I compiled it myself, function by function
12:33:02 malice example-button gives me division by 0
12:33:07 loke` Simply never use the addchar variations, and only use addstr, even if the string is only one "character" long.
12:33:40 haom hm.
12:33:50 haom well thats a suggestion I didnt expect.
12:34:38 loke` haom: That's because Unicode is complicated, and seemingly surprising for people who don't it.
12:34:43 loke` Don't worry, it happens to everybody.
12:35:13 loke` Hell, even I can be surprised sometimes, and I've worked with Unicode related issues for over 15 years.
12:40:35 Poenikatu malice: I've just compiled the (example-button) function with the previous function and it compiled and ran ok. I used (gtk-label-label) as the slot accessor.
12:42:27 Poenikatu malice: That is, (setf (gtk-label-label label) "The Switch is ON")
12:47:01 malice Poenikatu: that's good!
13:41:24 jfe hi all. i want to represent data as an unsigned 24-bit integer. i need bitwise 'and' and 'logical shift' operators. the boole function seems to be capable of handling 'and', but the only shift function i can find so far is 'ash' which does an arithmetic shift. am i better off using a bit vector, and if so, what's the cost relative to using an integer?
13:44:39 p_l bit-vector might be a better choice, indeed. The cost relative to fixnum will depend on implementation, but expect the difference caused by boxed type
13:44:55 loke` jfe: combine ASH with AND
13:45:11 p_l (so heap allocation, few more dereferences, etc.)
13:45:19 p_l ... or do what loke` said, that might work xD
13:45:50 loke` p_l: except LOGAND of course :-)
13:46:00 fluxit Hello - another noob looking for help as well: I'm having some trouble (style issues) when passing around &rest arguments. Here's an example of some problem code: http://hastebin.com/ebokayihoz.lisp
13:46:15 fluxit Anyone have any suggestions?
13:47:13 loke` fluxit: exactly what is your problem?
13:48:01 loke` fluxit: I'm sorry for not being able to look at your code. I can't look at dark backgrounds for more than a few seconds before my eyes cross.
13:48:27 fluxit line 31 of the haste- I don't know how to expand a list of list from an &rest param ... or even if that is something I should do- sorry for not being specific
13:48:46 ggole fluxit: seems like you should just pass a list of lists there
13:48:56 loke` fluxit: What do you mean "expand"? The arguments are passed as a sligne argument using &rest
13:49:15 fluxit An eye-friendly version ;) : http://pastebin.com/raw/4XkaVBxy
13:50:02 loke` oh thanks :-)
13:50:43 fluxit I guess I'm looking for a way to convert lists-of-lists into seperated lists (so that functions like intersect will work on them) however...
13:51:13 fluxit I think I'm doing something wrong, stylistically, to run into this problem in the first place... It just seems... wrong.
13:51:18 ggole I think you want a reduce/fold there
13:51:24 loke` fluxit: Nag, you're overthinking things
13:51:33 loke` Nah
13:53:49 fluxit (Also, is there some way to hide whatever fix [mapcar, reduce/fold, etc] inside of my functions? I really want to write something like the second to last function.)
13:54:56 loke` fluxit: in the second-to-last example? WOuldn't use use (apply #'intersection ...) there?
13:54:57 kenanb fluxit: if I only see the paste, damn my internet is slow
13:55:36 loke` no wait, I have misunderstood your code
13:55:39 fluxit loke` the second to last example isn't real code- it's what i'd like to write
13:56:15 ggole When you want to apply a two-argument function like intersection across the elements of a list, you probably want reduce
13:56:21 loke` Well INTERSECTION takes a number of lists as (&rest) arguments. So if you have a variable holdoing a list of lists, you'd have to call it using (apply #'intersction list-of-lists)
13:56:42 ggole Isn't intersection binary?
13:56:46 ggole clhs intersection
13:56:51 loke` Yes, like ggole says. APPLY, or better, REDUCE
13:57:05 loke` ah yes it is indeed
13:57:08 loke` so REDUCE it is then
13:58:27 ggole Hmm, you might need a stupid dance to handle zero or one arguments though
13:58:52 ggole intersection isn't smart about that like + and friends are
14:03:42 MoALTz_ ** NICK MoALTz
14:12:16 arpunk1 ** NICK arpunk
14:13:49 fluxit Well, reduce was what I wanted- thanks everyone- but... It's still ugly. I'm specifically looking at my prime-factors function
14:15:27 fluxit There has to be a better way to handle passing around &rest arguments, right? What if I had N functions that passed their &rests in the way that I do in the gcd functions- You'd have to strip off N sets of extra parens, no?
14:15:39 fluxit (So what am I doing wrong?)
14:16:35 kenanb no
14:16:47 kenanb you just pass the rest arguments using apply
14:16:49 fluxit (Rephrased: My prime-factor function has got to be the wrong way of handling that situation.. so what's the right way?)
14:17:04 kenanb that's it, then you don't strip off any parens
14:17:31 kenanb can you link to your code again fluxit?
14:18:39 fluxit (Is it okay to post code in here? ) Updated gcd:
14:18:40 fluxit (defun greatest-common-divisor (&rest args)
14:18:40 fluxit (apply #'max (reduce #'intersection (apply #'prime-factors args))))
14:19:07 fluxit Like I said- I'm trying to achieve this:
14:19:08 fluxit (defun greatest-common-divisor (&rest args)
14:19:08 fluxit (max (intersection (prime-factors args))))
14:20:07 fluxit (I'm trying to understand how to hide away all the excess list management)
14:20:27 phoe_krk fluxit: yes, mostly okay, as long as the code isn't a wall of text.
14:20:30 kenanb you shouldn't
14:20:37 phoe_krk Tiny snippets like these are fine.
14:21:35 phoe_krk But like kenanb said: apply and reduce are fairly necessary there. They tell people what you're doing with your lists.
14:22:24 phoe_krk You get a list, then APPLY a function to it. Then you REDUCE the resulting lists with INTERSECTION. Then you apply MAX to the results to find the maximum.
14:22:31 phoe_krk Sounds sane enough.
14:22:49 phoe_krk (max (...)) basically equals to (...) because MAX is waiting for more than one argument.
14:23:07 phoe_krk So does INTERSECTION.
14:23:17 fluxit Another example- what if you have something like this http://hastebin.com/apolosoxet.lisp colorless: http://hastebin.com/raw/apolosoxet
14:23:35 phoe_krk clhs another
14:23:35 specbot Couldn't find anything for another.
14:23:49 phoe_krk Oh, wait.
14:23:50 fluxit fake functions
14:23:55 fluxit just an example ;)
14:24:00 phoe_krk Three sets of nested lists?
14:24:12 phoe_krk Give me an example. I need an example set of data you need to be dealing with.
14:24:19 fluxit There isn't one
14:24:27 fluxit I'm just curious
14:24:45 fluxit (and I don't think I'm explaining myself very well :S)
14:27:34 phoe_krk fluxit: it's hard to speak of such general stuff without good examples.
14:27:50 phoe_krk "Three sets of nested lists" can look completely different based on who's reading the words.
14:27:54 kenanb fluxit: that is the right way to do it, you are doing list management because it is necessary, it might seem not like so for functions that expects a number of arguments that has similar characteristics, like the lambda list of #'+ etc, but usually a lambda list will be like (a b &rest args &key c (d nil d-supplied-p))
14:28:05 phoe_krk Give me a proper example of the lists you need to work on, and I'll try to show you a way of working with them.
14:28:52 phoe_krk Can be really simple, like '((a 1) (b 2) (c 3)) '((d 4) (e 5) (f 6)) '((g 7) (h 8) (i 9)) - there, three sets of nested lists.
14:28:59 phoe_krk That'
14:29:00 kenanb fluxit: and when your own functions will constantly deal with a list of arguments, why not using a parameter that expects a list?
14:29:12 phoe_krk That's how I imagine it.
14:31:40 kenanb fluxit: (defun test (my-list) (another my-list)) (defun another (my-list) (last my-list)) (defun last (my-list) (print my-list))
14:31:49 sigjuice any particular reason why libfixposix is not included in iolib?
14:32:08 fluxit But wont I always have to write boilerplate (like my prime-factors code http://hastebin.com/ebokayihoz.lisp http://pastebin.com/raw/4XkaVBxy) to handle single elements vs a list?
14:33:45 kenanb fluxit: did you look at my example above?
14:34:12 fluxit Yar
14:34:38 fluxit But it doesn't handle arbitrary amount of arguments
14:35:08 kenanb what do you mean?
14:35:53 sweater ** NICK Guest10262
14:36:07 fluxit The way #'+ does for example
14:36:18 kenanb how so
14:38:17 aeth fluxit: You probably want to iterate explicitly with do in your example code. Lisp is not Scheme.
14:38:23 phoe_krk fluxit: there's a &REST there. That handles an arbitrary amount of arguments.
14:39:27 fluxit Lol.. I'm not explaing myself well. Do you guys know python? I'm looking for tuple expansion in lisp (for the &rest args)
14:39:57 kenanb fluxit: I believe you are trying to solve a problem that only exists in your mind. those two are totally different interfaces to pick for a function, you need to chose one, which brings us to question "what your function is for?", is it an internal function that will always deal with lists? or is it an external function that will expect an arbitrary set or arguments, it can't do both, at least not without being explicit in your call to
14:39:57 kenanb function
14:40:23 phoe_krk fluxit: Lisp is a very good language, but it doesn't make for a very good Python.
14:40:30 phoe_krk (defun myplus (x &rest args) (if (null args) x (apply #'myplus (+ x (car args)) (cdr args))))
14:40:38 fluxit kenanb I'm guessing I'm trying to both- or looking for a way to have both
14:40:40 phoe_krk This handles any amount of arguments just like #'+ does.
14:41:11 kenanb fluxit: you can't, not because the language doesn't let you do it, but because it is a completely wrong thing to request
14:41:36 fluxit phoe_krk: I'm not having an issue handling arbitrary amounts of arguments, I got that. I'm having an issue hiding away my function interface
14:41:49 kenanb fluxit: therefore the language doesn't let you do it
14:42:07 phoe_krk fluxit: hiding away your function interface? why and what would you want to achieve through it?
14:43:04 fluxit NOT necessarily for those specific functions, but in a general sence
14:43:06 fluxit sense*
14:43:10 phoe_krk fluxit: I see what you're trying to achieve. My question is, why?
14:43:29 kenanb fluxit: you are not trying to "hide away" your interface, you are trying to change it, therefore you need a wrapper, and a wrapper that changes the interface is not boilerplate, it is part of your algorithm.
14:43:33 fluxit I just wanted to know if it could be done
14:43:36 phoe_krk kenanb: I don't agree with "lisp not allowing him to do that". He can do it if he's patient enough.
14:43:44 phoe_krk That's totally achievable with macros.
14:43:49 fluxit (academic circle jerk)
14:43:50 kenanb phoe_krk: yes, and it is wrong
14:43:50 phoe_krk But I say it'll give him much more trouble than it's worth.
14:43:58 phoe_krk fluxit: yes, it can be done.
14:44:18 phoe_krk But there's very little reason to do it.
14:44:58 fluxit why?
14:45:03 phoe_krk You can do it Java style and write every single piece of code in a whole new class and make a interjection-boilerplate-string-factory-factory-generator.
14:45:08 phoe_krk But totally why?
14:45:17 fluxit phoe_krk you lost me
14:45:31 phoe_krk fluxit: why do you want to abstract it this much?
14:45:32 kenanb phoe_krk: yes, of course, you could do it with macrology, but it would be a hack, it is not a good problem to solve.
14:45:44 aeth fluxit: I think the point is that you have to code idiomatic code in the language you are using.
14:46:30 fluxit phoe_krk to avoid having to write things like my prime-factors example
14:47:00 fluxit or IF i have to handle cases like that, then to only have to handle them outside or inside the functions, not both
14:47:07 fluxit (though I'm not certain I do..)
14:47:21 fluxit I wasn't lying when I said I was a noob at the beginning ;)
14:47:22 phoe_krk fluxit: you avoid having to write things like your prime-factors example at the expense of having to write a real, *real* lot of code necessary to hide function application and reduction like you want to.
14:47:26 phoe_krk fluxit: better.
14:47:33 phoe_krk Give me an example in Python at what you're trying to do.
14:48:04 phoe_krk Because I totally don't get what you said about "handling cases". I don't get it just yet.
14:48:42 fluxit (give me a moment, it's been awhile since i've written python)
14:49:51 phoe_krk fluxit: you basically can write your own vision of Common Lisp by creating a new package and importing completely nothing; in there, you can write your own intersection function, your own max function, your own prime-factors that hide everything away the way you did.
14:50:09 phoe_krk But this way, you're already creating a new dialect of Lisp.
14:50:43 phoe_krk It's a great, awesome feeling to extend Lisp the way you want it to function.
14:51:01 phoe_krk But to bend the rules, you first need to get to know them, and you need to get to know them well. :P
15:00:01 fluxit I *think* that its valid python.. but I didn't/couldn't actually check it (no primes())... but the idea is there either way: http://pastebin.com/raw/xhFC2JSN
15:00:46 aeth that link doesn't work for me
15:00:53 aeth "Please refresh the page to continue..."
15:03:19 phoe_krk Lisp actually makes a difference between atoms, lists, and lists of lists.
15:03:33 phoe_krk Each function in Lisp has a so-called lambda list. Basically, a list of arguments it expects.
15:04:32 phoe_krk If a funciton expects an atom, you don't put a list in that spot. It'll err out.
15:04:43 phoe_krk If a function expects a list, don't put atoms in there, it'll err out as well.
15:05:20 fluxit phoe_krk: are there other categories besides atoms lists and LOLs?
15:05:27 phoe_krk There's no LOL, actually.
15:05:29 phoe_krk A LOL is a list.
15:05:35 phoe_krk Everything in Lisp is either an atom or a list.
15:06:04 phoe_krk That's the fundamental thing in the Lispy philosophy.
15:06:10 fluxit But it's not (it is- I get that) but a LOL doesn't behave the same a list does in a function
15:06:14 jasom of course calling a vector or a hash table an "atom" is perhaps silly
15:06:37 phoe_krk jasom: technically, they are atoms, despite them containing other stuff.
15:06:41 kenanb fluxit: the answer to your question in comment is that you shouldn't.
15:06:45 phoe_krk fluxit: depends on what *the function* does.
15:06:53 phoe_krk If a function expects a list of lists, it'll work on a list of lists.
15:07:00 phoe_krk And *might* err out on a list of atoms.
15:07:07 fluxit so if you wanted to create general purpose functions you'd need to check for LOL- If I wanted to write a intersect function that could handle both cases:
15:07:09 phoe_krk And *probably* will err out on an atom.
15:07:10 aeth fluxit: if you do (map 'list #'foo sequence) it's more generic than (mapcar #'foo list) so you'd be able to handle vectors as input
15:07:18 phoe_krk fluxit: general purpose functions?
15:07:31 phoe_krk What do you mean, general purpose function?
15:07:31 fluxit (int '(3 4) '(4 5) ) and (int '((3 4) (4 5))
15:07:39 fluxit where int == intersect
15:07:50 kenanb fluxit: you shouldn't even handle data with completely different semantics from a single interface manually in a single function most of the times, let alone doing it automagically
15:08:20 phoe_krk fluxit: you totally shouldn't.
15:08:25 fluxit Why?
15:08:31 aeth fluxit: Why not just have a (prime-factor int) and a (prime-factors sequence) instead of trying to be too generic?
15:08:33 axion fluxit: why not write implementations for both variants with a common api (Generic function)
15:08:46 phoe_krk This is a field for many, many mistakes.
15:08:53 phoe_krk That can be made and will be made this way.
15:09:24 fluxit Guys, I get that it CAN be done other ways- I'm just trying to understand WHY I shouldn't/can't do it
15:09:31 fluxit It seems like it would make for nice, simple code
15:09:32 aeth (My example names were poorly chosen.)
15:09:55 fluxit CAN/SHOULD*
15:10:03 phoe_krk Let me try to explain.
15:10:12 fluxit (I guess I'll put should, not necessarily that I agree ;) )
15:10:27 phoe_krk From my point of view, it's much easier to have a function that has a well-defined input and produces a well-defined output.
15:11:48 phoe_krk And, depending on what kind of data you have, utilize APPLY/FUNCALL/MAP/MAPCAR/REDUCE to bend your data to the function's inputs.
15:11:57 phoe_krk It makes for much, much cleaner code inside functions.
15:12:23 phoe_krk And your lambda list doesn't then look like (my-fun &rest args), giving you no help on what you're doing.
15:12:43 kenanb fluxit: because if the language would try to do it, it would be trying to infer the application method from the structure of the parameter value. what if your function actually works with lists as parameters? like append, what would you expect APPEND to do in such ambiguity?
15:12:49 phoe_krk It might look like (my-fun function list &rest other-lists).
15:12:50 phoe_krk Oh.
15:12:53 phoe_krk Just what kenanb said.
15:13:30 fluxit (you guys are losing me a bit)
15:13:44 phoe_krk Let me give you an example.
15:13:45 fluxit ( @kenanb ^ :P )
15:13:57 phoe_krk APPEND function joins lists together, right?
15:14:04 fluxit yeah
15:14:06 phoe_krk (append (list 1 2) (list 3 4) (list 5 6))
15:14:12 phoe_krk => (1 2 3 4 5 6)
15:14:16 fluxit k
15:14:47 phoe_krk Let's say you want to make it "generic".
15:14:51 phoe_krk So it "knows" what it's doing.
15:15:02 phoe_krk What would (append (list (list 1 2) (list 3 4) (list 5 6)) (list 7 8)) evaluate to?
15:15:13 phoe_krk In other words,
15:15:18 fluxit (append '((3 4) (5 6)))
15:15:23 fluxit (3 4 5 6)
15:15:27 phoe_krk (append '((1 2) (3 4) (5 6)) '(7 8))
15:15:28 fluxit Yeah- I'd like that :)
15:15:46 phoe_krk What would this evaluate to?
15:16:13 fluxit ((1 2) (3 4) (5 6) 7 8)
15:16:23 phoe_krk Yes, that's how it'd work.
15:16:29 phoe_krk And, because of this.
15:16:41 phoe_krk (append '((3 4) (5 6))) would evaluate to ((3 4) (5 6)).
15:17:08 phoe_krk Because your version of APPEND seemingly works only on one argument.
15:18:04 phoe_krk APPEND merges the lists it takes as its arguments. It doesn't do anything to the contents of the lists.
15:18:27 kenanb fluxit: but append takes an arbitrary number of arguments itself. so provided it is feed only a single argument, append should be returning its single argument unchanged, since there is nothing else to append. so the programmer would expect (append '(1)) => (1), and therefore (append '((1 2) (3 4))) => '((1 2) (3 4))
15:18:30 phoe_krk If you have a list of lists you want to have merged, you need to APPLY the function APPEND to the list.
15:19:26 fluxit Okay- I think I get it for append- You need it to be the identity function for just 1 element that way you can recurse properly, right?
15:19:27 kenanb fluxit: but your append returns (1 2 3 4), so the question is how would you guarantee what is "the right thing"?
15:19:48 phoe_krk fluxit: yes.
15:20:03 phoe_krk Appending nothing to a list should result in the original list.
15:20:08 phoe_krk It sounds fairly logical to me.
15:20:11 phoe_krk Also, in some cases.
15:20:20 phoe_krk You might take the "what if" approach.
15:20:33 malice what if rocks
15:20:35 phoe_krk You can expect one or more lists and want to append them just in case.
15:21:05 phoe_krk Actually, a list of 0+ lists.
15:21:14 kenanb fluxit: yes but not only for recursion, what if your function appends a list it gets as argument at some point and it doesn't know how many arguments it will get, but it surely wouldn't expect to append the nested lists to each other just because it got a single list instead of multiple lists
15:21:28 phoe_krk Therefore applying APPEND to a list of lists. If it's an empty list, it'll return an empty list. One list, one list. Multiple lists, appended list.
15:23:46 fluxit All of this is making sense... for append.
15:23:54 fluxit But I don't see why it applies to functions like max
15:24:37 kenanb fluxit: so you expect function application to work in a certain way for some functions and another way for others?
15:24:52 kenanb that would be astonishing
15:25:01 fluxit Why does it have to be astonishing?
15:25:05 malice fluxit: hint: you can always use (documentation 'your-function-name 'function) to see what your compiler wrote about the function. e.g. (documentation 'max 'function)
15:25:33 fluxit It seems straightforward to me that (max '((3 (4))) 3 2 '(1) ) COULD return 4
15:25:44 malice it couldn't
15:25:49 kenanb fluxit: what?
15:25:52 malice I mean, it could, but it shouldn't
15:25:52 fluxit malice: I know it can't
15:26:01 malice it's like an instant wtf and you don't want that
15:26:05 fluxit I'm saying it would be a whole lot more useful if it did
15:26:10 malice nah
15:26:19 fluxit malice why?
15:26:26 kenanb fluxit: it seems straightforward to most that it would error
15:26:37 malice (max '((3 (4))) ) should return what?
15:26:41 phoe_krk fluxit: that's a type error.
15:26:45 malice '((3 (4))) ?
15:26:48 kenanb fluxit: and that is the least astonishing behaviour
15:26:50 phoe_krk MAX expects numbers.
15:27:03 phoe_krk It wants numbers.
15:27:11 phoe_krk You don't put lists where it expects numbers.
15:27:28 fluxit All of this *SEEMS* arbitrary
15:27:41 malice In your example? Yeah, I think so.
15:27:45 fluxit Why shouldn't I write a better-max function that can handle anything?
15:27:59 phoe_krk Well, you can.
15:28:01 fluxit (Ignore the max thing- you understnad my point, yeah?)
15:28:10 fluxit Again, I get that I can
15:28:11 axion (apply #'max (alexandria:flatten '(((3 (4))) 3 2 (1)))) => 4
15:28:17 phoe_krk ^
15:28:19 malice exactly
15:28:27 fluxit But everyone is insisting it shouldnt be done... without giving reasons why
15:28:43 fluxit other than 'astonishment'
15:28:44 phoe_krk fluxit: because your code becomes messy the moment you can accept anything anywhere.
15:28:52 malice fluxit: You have many philosophies. One of them is that you write a function that does one thing, and does it well.
15:29:08 phoe_krk And in some cases gives you unpredictable behaviour.
15:29:11 malice fluxit: what you're proposing is a function which works "somehow, generic, i guess"
15:29:15 phoe_krk Like in case of APPLY.
15:29:17 fluxit malice I would ague that my better-max does one thing- it tells you teh max value
15:29:39 phoe_krk fluxit: let's assume another thing.
15:29:44 phoe_krk You feed MAX a list instead of a number.
15:29:53 phoe_krk I'd rather have MAX err out on me that I fed it something I shouldn't have.
15:30:04 phoe_krk Rather than have it shrug, continue, and act like everything's fine.
15:30:08 malice fluxit: Yeah, but max value of what? What is "the max value of the list"? Or a vector? Or of a class instance? It's not about how you word it, but see that in your words "max value" is vague,
15:30:34 phoe_krk I'd rather have it tell me something went wrong, than have it work with value that might have been a mistake.
15:30:38 kenanb fluxit: we have giving you like a lot of reasons actually, and I really like your example because it exaggerates it to the point of absurdity, which makes it obvious how such approach would make the "list" structure totally pointless, because its characteristics cannot even efect the algorithm at that point, it is as if you want the whole nesting to always be "flattened" automatically.
15:30:44 phoe_krk And/or garbage.
15:30:48 fluxit phoe_krk that makes sense
15:31:36 phoe_krk Also a thing where, in Javascript, 1234567890123456789012345678901 - 1234567890123456789012345678900 might give you 0.
15:31:43 phoe_krk Because of the floating point arithmetics.
15:31:45 phoe_krk Or whatever.
15:31:55 phoe_krk Dynamically converting types everywhere, all the time.
15:31:58 phoe_krk A complete mess.
15:32:56 phoe_krk Your BETTER-MAX might perhaps catch more cases.
15:32:59 fluxit kenanb: Let's take it out of absurdity then http://pastebin.com/raw/24pxL6hk
15:33:10 phoe_krk But catching more cases also means being much more prone to programmer errors.
15:33:20 fluxit Theres nothing (IMO) about my desired gcd function- it's far cleaner)
15:33:26 fluxit nothing absurd*
15:33:36 phoe_krk In your example.
15:33:41 phoe_krk You call MAX with a single argument.
15:33:56 phoe_krk MAX *expects* multiple arguments.
15:34:00 kenanb fluxit: you cannot take it out of absurdity, that is the good thing about your example, if you want function application work in that way, it should also be working for the absurd case.
15:34:02 axion normally absurdity and efficiency are at opposite extremes
15:34:09 phoe_krk So does INTERSECTION.
15:34:18 kenanb fluxit: that is why we have been saying you shouldn't even expect such behaviour
15:34:21 phoe_krk So does PRIME-FACTORS I think.
15:34:46 fluxit I think
15:34:59 fluxit I just *got* what problem is/was
15:35:16 fluxit I want my prime factors function to be able to return multple answers
15:35:21 fluxit and lisp doesn't support that
15:35:24 phoe_krk WHAT
15:35:29 axion VALUES
15:35:36 p_l fluxit: what kind of multiple-values?
15:35:42 phoe_krk (defun myfun () (values 1 2 3 nil (list 4 5 6)))
15:35:45 phoe_krk Put this in your REPL
15:35:50 p_l fluxit: because unlike Python, CL supports multiple value returns
15:35:57 phoe_krk Then (nth-value 0 (myfun)) to (nth-value 5 (myfun))
15:36:09 phoe_krk Actually, to (nth-value 4 (myfun))
15:36:20 haom when I get thrown in to sbcl's low-level debugger, with an error like: "glibc detected *** sbcl: free(): invalid next size (fast):" is this an error the sbcl devs should possibly want to know about?
15:36:41 phoe_krk haom: they should, I think. IMO, #sbcl is where this should land.
15:37:18 haom ok, thanks.
15:38:04 fluxit but isn't my-fun really just returning a list
15:38:08 kenanb fluxit: list actually does support returning multiple values, but it will not help you. in fact it will make your situation even worse, because now you have to bind multiple values to a &rest args manually, then do the same thing :D
15:38:09 fluxit that you're pulling things out of?
15:38:15 phoe_krk fluxit: no.
15:38:16 phoe_krk Call it.
15:38:28 kenanb s/list/lisp
15:38:34 phoe_krk It returns five values.
15:38:53 phoe_krk With the first one being the "default" one that gets passed to other functions.
15:38:55 p_l fluxit: no, it returns separate values on the call stack, doesn't allocate any kind of list or other structure
15:39:17 p_l fluxit: and you have multiple-value-bind which allows you to bind those values directly into symbols
15:39:53 phoe_krk (multiple-value-bind (a b c d e) (myfun) (format t "~A ~A ~A ~A ~A~%" a b c d e))
15:39:55 phoe_krk Try this.
15:40:03 fluxit So couldn't I use values in my prime-factors function to return seperate lists? Which would then work with intersection?
15:40:14 fluxit (Oh wait, intersection is binary- so intersection* then)
15:40:28 phoe_krk fluxit: the first return value.
15:40:59 phoe_krk Also, what is intersection*?
15:41:38 fluxit ( phoe_krk: been doing the little schemer :P- A made up intersection function which isn't binary)
15:42:14 phoe_krk Oh.
15:42:21 kenanb I think it really doesn't matter because fluxit will need all the values #'prime-factors returns ALL THE TIME, therefore prime-factors should be returning a sequence after all
15:42:32 phoe_krk (reduce #'intersection lists)
15:42:44 phoe_krk A made-up intersection function that isn't binary. The Common Lisp style.
15:42:51 phoe_krk :3
15:42:55 fluxit :)
15:43:58 phoe_krk Really.
15:44:12 phoe_krk Lisp does a very good thing with handling higher-order functions.
15:44:18 phoe_krk I mean.
15:44:23 phoe_krk Higher-order functions handling other functions.
15:44:38 phoe_krk You have a function that takes two arguments, bam, it takes any amount of arguments with reduce.
15:44:52 phoe_krk FUNCALL and APPLY also are there for calling functions with unknown/known amounts of arguments.
15:45:09 phoe_krk MAP takes a function and calls it repeatedly with values taken from the lists.
15:45:34 phoe_krk MAPCAR takes a single-argument function and calls it on each thing on the list.
15:46:08 phoe_krk REDUCE takes two arguments of a list, calls a function on them, then puts the result back on top of the list, and repeats until there's just one thing on the list. Which gets returned.
15:46:26 phoe_krk With them, you don't really need to write functions that are Swiss multitools.
15:46:42 phoe_krk You can write simpler functions with well-defined arguments and just bend your data so it all fits.
15:47:12 phoe_krk FIND, REMOVE, REMOVE-IF, and so on. They all take test and/or key functions as arguments, too.
15:47:16 fluxit It just seems so... ugly :P
15:47:21 fluxit Cool
15:47:24 phoe_krk Very useful though.
15:47:30 phoe_krk Your functions don't need to guess *at all*.
15:47:41 phoe_krk You tell your functions how to behave.
15:47:46 phoe_krk And they behave just the way you tell them to.
15:47:50 fluxit Exactly
15:47:56 fluxit I don't want to tell them how to behave
15:48:00 fluxit I want them to just do it
15:48:20 fluxit but
15:48:23 phoe_krk Then be ready for unspecified behaviour.
15:48:32 phoe_krk Unless you specify a lot, *lot* of cases.
15:48:45 phoe_krk And pray your specification and the spec's implementation is correct.
15:49:23 fluxit I've got to go- I've managed to avoid my OS homework for far too long now :) Thanks everyone for all the help, I'll play around with values (and see if I can't come up with a good 'better-max' example- I'm still not completely sold that it's a bad idea) and see if I can't get the behavior I'm looking for.
15:49:24 fluxit Fair enough- I can see how it can lead to a lot of bugs. I definitely wont be doing it outside of personal things.
15:49:37 fluxit Anyway, thanks again, afk~
15:49:37 phoe_krk No problem! Feel free to come around again.
15:49:46 phoe_krk There's lot of good discussion to be had.
15:49:50 fluxit :)
15:49:52 phoe_krk :3
15:51:06 pjb` phoe_krk: If a function expects a list, you DO put ONE atom in there: NIL!
15:51:36 pjb` phoe_krk: no, something in lisp can be BOTH an atom AND a list! NIL!
15:51:48 pjb` phoe_krk: everything in lisp is EITHER an atom or a cons cell.
15:52:20 phoe_krk Time for my daily beating for getting Lisp wrong! :D
15:52:21 pjb` It's increadibly you have such misconceptions after so long. What have you been doing?
15:53:11 phoe_krk I seemingly need to get the very theoretical basics repeated a few more (tens of) times.
15:53:16 pjb` jasom: calling atoms atoms is silly too (apart from ¹H), given they're made of protons and neutrons.
15:53:51 pjb` (and even for ¹H, there are actually 3 quarks in its proton).
15:53:52 phoe_krk pjb: I'm close to remembering that there are actually no unbound lexical variables. I'll get the things you mention remembered, too.
15:54:01 fourier Any LW users around?
15:54:10 pjb` phoe_krk: :-) Good, the important thing is to make progress.
15:54:12 phoe_krk fluxit: but what pjb said above, yes.
15:54:13 fourier The problem I'm facing is what I cannot debug in LW packages loaded
15:54:13 fourier with QL
15:54:16 phoe_krk pjb`: I'm making it. :P
15:54:22 phoe_krk Slowly, but surely.
15:54:28 fourier if I recompile the file in LW and set (break) in my function,
15:54:28 fourier in the execution I still get: Debug-Break in process "Cocoa Event
15:54:28 fourier Loop" {undebuggable process}
15:54:35 pjb` fourier: perhaps you need to recompile them with a different optimization setting?
15:54:46 phoe_krk Cocoa Event Loop?
15:54:48 phoe_krk Sounds like OS X.
15:54:57 pjb` Perhaps you need to run it in a different thread.
15:55:11 fourier adding (declaim (optimize (debug 3))) in the beginning of the file doesn't help
15:55:27 fourier in compilation output I see ;;; Safety = 3, Speed = 1, Space = 1, Float = 1, Interruptible = 1
15:55:27 fourier ;;; Compilation speed = 1, Debug = 2, Fixnum safety = 3
15:55:27 fourier
15:55:35 pjb` Yes, it seems that LW doesn't want to debug the main thread, in which it implements the debugger GUI.
15:55:42 pjb` Seems natural.
15:55:43 fourier so should be ok probably...
15:56:05 fourier No it is not this problem. It can debug ok own examples
15:56:08 pjb` So try to run that code in a different thread. If that's GUI code, then perhaps you could debug it with slime?
15:56:51 pjb` fourier: otherwise, perhaps you should ask on the lispwork mailling list.
15:56:53 fourier it is what I guess what I 1) load my app with quicklisp 2) set a breakpoint 3) try to compile a file with LW
15:58:20 fourier I guess it is _probably_ something with where to place .xfasl files. While loading with QL it places them into ~/.cache/common-lisp.... and when I compile with IDE the same file the .xfasl appears in the same directory as a source file.
15:58:36 pjb` This is most certainly unrelated.
15:59:06 pjb` The problem is that you're trying to debug the main thread: Debug-Break in process "Cocoa Event Loop" {undebuggable process}
15:59:19 pjb` with a debugger that is implemented using the main thread.
15:59:42 pjb` So instead, try to debug it with slime (sldb expressions are evaluated by swank in different threads).
16:00:00 fourier but how come I can debug other CAPI examples with the same debugger?
16:00:22 pjb` I don't guarantee that you will be able to debug the Cocoa Event Loop with slime/sldb/swank, but this is what I do with ccl which has the same problem.
16:00:49 pjb` They are probably doing something different. What ql system is it?
16:02:17 fourier it is my own app
16:02:30 pjb` And you're using CAPI for the GUI?
16:02:41 fourier yes. in the same way as in examples.
16:02:53 pjb` I don't know, can you call CAPI in other threads?
16:03:14 fourier just verified.
16:03:30 pjb` Is that a yes?
16:03:49 fourier no, I meant what I do the same as in examples
16:04:05 pjb` there must be a difference obviously.
16:04:29 fourier One can't call capi from other threads - there are special functions to execute something in UI thread.
16:04:29 pjb` I would try: (ql:quickload :bordeaux-threads) (bt:make-thread (lambda () (your-application)))
16:04:42 pjb` Ok, so it won't work.
16:05:08 pjb` I think you will have to ask on the lispworks mailling list.
16:05:39 fourier Yes, just asked. Will see what the people could come up with.
16:20:21 pjb` phoe_krk: "join" has some kind of connotation that is not valid for CL:APPEND. what CL:APPEND does is to build a new list that contains all the elements of all the list but the last, and NCONC that last list, so the result share structure with that last list. In a way, it joins only the new prefix with that last list. I would say that it's NCONC that j oins the lists together, not APPEND. mind CONCATENATE, which will return an
16:20:21 pjb` entirely fresh list.
16:21:14 pjb` Also, by the definition of append, (append '(1) 2) #| --> (1 . 2) |# the last argument doesn't need to be a list!
16:21:21 pjb` (append 42) #| --> 42 |#
16:21:43 pjb` You cannot say "join list" when there's only 42!!!
16:23:24 pjb` fluxit: what about (max '(3 #(4) #S(point :x 5 :attributes (6 #(7))))) ? Should it return 7? How would it know how to walk rand lisp objects?
16:23:30 pjb` random
16:44:42 fourier pjb`: yes it looks like it is something what you've described. In other examples I never verified UI callbacks, rather code executed in constructors. so need to find another way to debug. (the solution with running UI explicetly in another thread doesn't work with debugging either)
16:45:09 pjb` fluxit: (multiple-value-call (function intersection) (function-returning-sets-in-multiple-values))
16:45:35 pjb` Well, function-returning-2-sets-in-multiple-values since intersection takes only two of them.
16:45:58 pjb` but function-returning-2-sets-in-multiple-values could return more values, for the optional parameters of intersection.
16:47:57 pjb` fourier: what are you debugging? The code that needs to be debugged often can be run outside of the main thread context. You could stub the CAPI functions if it calls them directly. Think "unit tests". That's where most of the debugging is/should be done.
16:59:46 fourier yes I understand it all. of course I can just add logging as I usually do; but the problem is what I cannot debug the ui code with a graphical debugger seems strange to me; I was able to debug Cocoa C/ObjC code in xcode without problems and this situation just feels strange for the expensive IDE, one of advantages of which is a UI framework.
17:11:30 kenanb can you confirm these assumptions from standard compliance perspective: 1) structures are clos classes that inherit from structure-object instead of standard-object 2) therefore methods can specialize on structures because they are clos class instances 3) make-instance will work on structure classes 4) unlike clos class instances, the behaviour is undefined when trying to access a slot that is not manually set or had no initform, so
17:11:30 kenanb there is no guaranteed call to SLOT-UNBOUND when so
17:11:49 kenanb I think I am wrong with point 3
17:12:28 fiddlerwoaroof clhs defstruct
17:14:12 kenanb fiddlerwoaroof: thank you but I am well aware of the page :) I was trying to clarify my understanding of structures according to that page and several other references to structures
17:14:25 fiddlerwoaroof kenanb: I was looking at it for my own reference.
17:14:35 kenanb ah, I see, pardon me.
17:15:00 phoe_krk_ ** NICK phoe_krk
17:15:35 Baggers Shinmera: Hi, does staple include doc-strings for non-exported symbols?
17:15:59 fiddlerwoaroof clhs make-instance
17:17:31 fiddlerwoaroof kenanb: It looks like make-instance is defined not to work on structs.
17:23:08 kenanb fiddlerwoaroof: hmm, yes, so my point with 3 was indeed wrong, sbcl make-instance works on structures but only to allocate them, not to initialize their slots
17:25:59 emaczen How can I replace a subsequence of a list with a single element?
17:26:20 emaczen #'replace doesn't work because it only will replace the min of the bounds
17:26:27 Bike clhs fill
17:28:01 emaczen Bike: Awesome! Thanks
17:30:46 emaczen Bike: Wait, I mispoke
17:31:29 emaczen I want to replace a subsequence with ONE element (so delete the subsequence and insert the element)
17:32:17 Bike that's more complicated, you'll have to copy the subsequent element backwards and then resize the sequence.
17:32:30 emaczen (delete-if #identity sequence :start i :end j) keywords seems to delete the rest of the list
17:32:53 Bike well, no, if it's a list you could do it differently
17:33:13 emaczen How?
17:33:45 Bike (setf (car sublist) element (cdr sublist) cons-after-the-sublist)
17:34:08 Baggers Is there a way to make a package export all the exported symbols of a package it is :use'ing? (without listing them all under :export)
17:34:33 Bike no, but you can make that list programmatically.
17:34:38 fiddlerwoaroof clhs do-present-symbols
17:34:38 specbot Couldn't find anything for do-present-symbols.
17:34:46 fiddlerwoaroof clhs do-symbols
17:35:20 Baggers Bike: fiddlerwoaroof: thanks, I'll use this approach then
17:35:46 fiddlerwoaroof Baggers: it might be easier to use loop...
17:36:26 Baggers It it legal to have a macro write a package definition right?
17:36:28 Jonsky I found that there're GUI automation libraries in other languages. Is there any in lisp? I mean a library to control the mouse and keyboard
17:36:47 fiddlerwoaroof Baggers: yes, that's what defpackage does.
17:37:04 kenanb Jonsky: a library to control the mouse and keyboard?
17:37:19 Bike metal gear?
17:37:22 Baggers fiddlerwoaroof: great, I had hoped it wasnt handled specially somehow
17:37:29 fiddlerwoaroof (loop for x being the present-symbols in 'some-package do (export x))
17:37:30 kenanb Jonsky: can you provide an example library name from another language, I am confused
17:37:35 Bike i remember using something like that to cheat in runescape. i don't know that it's common, though.
17:37:35 fiddlerwoaroof Or something like that should work.
17:37:44 Jonsky kenanb: wait a sec
17:37:46 p_l Jonsky: depends. You can use Windows' GUI automation protocols from any Lisp that can use COM objects, on OSX you can link through Obj-C bridge (so CCL will have it easiest, I guess). On Linux you'd have to implement your own ATK bus client or call to C libs
17:37:53 Baggers fiddlerwoaroof: and yes, that loop subclause looks much nicer
17:38:01 Bike kenanb: a library to send software mouse and keyboard movements to the system, so that you can automate tasks that only have a graphic interface, and such.
17:38:06 p_l Jonsky: we are missing a proper library for Selenium, though it should be easy to implement
17:38:17 p_l Bike: no serious UI automation uses that, though ;)
17:38:25 p_l * did some projects involving UI automation
17:38:27 Bike runescape is super serious
17:38:27 kenanb Bike: ah, those
17:39:08 Jonsky p_l: yes I was going to ask about selenium too
17:39:34 kenanb Jonsky: ok, I see, thank you.
17:39:36 fourier Jonsky: for UI authomation on OSX you can probably use native Automator app
17:39:38 p_l Jonsky: Selenium currently doesn't have a client library, but it should be doable in not-too-big timeframe as all the necessary parts are available
17:39:52 p_l fourier: Automator is a bit different beast, iirc
17:40:03 p_l that said, Cocoa has a native UI automation interface
17:40:06 Jonsky p_l: and I have no idea what you were talking about in the rest of the reply :(. I should learn more then.
17:40:34 Jonsky fourier: oh, I've forgotten that one haha
17:40:43 p_l Jonsky: I used UI automation for end-user tests of GUI applications (i.e. we mimicked real user, just like Selenium does for WWW)
17:40:58 p_l but I used TestStack.White in .NET
17:41:28 kenanb even the idea of relying on such thing for automation makes me shiver tho :)
17:41:48 kenanb tho it seems perfectly legit for testing
17:41:57 p_l White used windows native Automation interfaces
17:42:30 p_l kenanb: UI Automation interfaces are used pretty much by two kinds of applications - Screen readers (and other accessibility tools) and testers
17:43:39 fourier p_l: and by gamers to create bots to farm stuff in games :)
17:43:41 kenanb p_l: screen readers for like PDF files or HTML pages?
17:43:50 pjb` fourier: in the case of Xcode, the debugger is in Xcode, a different process than the application you are debugging. The equivalent situation is to use slime!
17:44:36 fourier pjb`: yes exactly. I thought it is implemented in similar way in LW. Sad what it isn't :)
17:44:59 p_l kenanb: screenreaders for the whole OS
17:45:11 p_l fourier: games don't export accessibility interfaces
17:46:23 fourier p_l: aah ok
17:46:56 pjb` kenanb: in LW, the debugger and your code both work inside the same LW application. It's more like when trying to debug emacs code inside emacs. Well, emacs still has two parts: one written in C and one written in emacs lisp, you wouldn't debug inside emacs the part written in C actually. The event loop processing in emacs is written in C, so while you can still botch the emacs image to the point of rendering it useless, some sanity
17:46:56 pjb` is still maintained. Not so much with what you're trying to do in lispworks.
17:47:04 pjb` s/kenanb/fourier/
17:47:11 kenanb I stand corrected
17:47:27 Indecipherable Game bots hook ingame functions I think? Or something
17:47:43 p_l Indecipherable: usually
17:47:55 p_l there are some mad libs written for that
17:48:09 p_l (MS Flight Simulator has this as pretty much main extension method...)
17:48:18 pjb` kenanb: you have to remember that structure-class is not (necessarily) a standard-class. That's why defmethod work on structure-class and its subclasses, but not make-instance of slot-value.
17:48:53 pjb` kenanb: also, integer is a built-in class which is also in a way, integrated into clos, given that defmethod works on built-in classes too. (class-name (class-of 42.0)) #| --> single-float |# etc.
17:49:35 Indecipherable I think starcraft had an api for this sort of thing actually, not sure. "AI" bot fights being a thing and all
17:49:38 kenanb pjb`: hmm, yes. so my other assumptions are right, except the make-instance one, right?
17:50:06 pjb` emaczen: you can use com.informatimago.common-lisp.cesarum.sequence:replace-subseq, of course.
17:50:24 pjb` kenanb: yes.
17:51:55 kenanb pjb`: I believe there is an exception to assumption number 4 tho, if the type of the structure is a list or vector (in which case it is not even a real structure anymore but still) the slots that are neither manually initialized nor provided an initform should still default to a value. since a vector or list will be built out of them
17:52:03 pjb` emaczen: (let ((seq (list 1 2 3 4 5 6 7 8))) (replace-subseq '(0) seq 2 6) seq) #| --> (1 2 0 7 8) |#
17:52:19 pjb` kenanb: you are correct :-)
17:52:35 fourier pjb`: Yes I got it. I just thought they could implement it as a separate process, but they haven't. Speaking of it, what is the most popular (and supported) logging library for CL, which could dump structs and class instances ? :)
17:52:46 pjb` then you have objects of system classes vector or list.
17:53:15 pjb` fourier: I've not studied the various logging libraries.
17:54:13 fourier pjb`: sorry ,it is rather question to the public.
17:54:25 kenanb pjb`: or maybe it is permitted that an error can be raised on creation in case of absence for such slots as an alternative to initializing to something?
17:55:09 pjb` the default default slot initform for structures is nil.
17:56:49 pjb` Baggers: notice that it's in your best interest not to use defpackage in your macro expansion, but to call directly the functions make-package, export, import, use-package etc… The problem with defpackage is that its semantic upon repeated calls are implementation specific.
17:57:22 kenanb pjb`: you mean for all types of structures or list/vectors? because the standard says what happens in an attempt to read them when they are not provided and not initformed is undefined
17:57:25 pjb` or, you can use a version of com.informatimago.common-lisp.lisp-reader.package:defpackage
17:57:41 pjb` kenanb: for all types of structures.
17:58:44 pjb` kenanb: oh, you're right. I thought it was nil by default. Indeed, that means that even for a vector or a list, it might be something else than nil…
17:59:59 pjb` So we should always give an initform for structure slots…
18:00:10 pjb` (giving nil is costless, really).
18:00:21 Baggers pjb`: That's very interesting, why would there be multiple invocation in a case where the macro expands to a defpackage.
18:01:05 pjb` Baggers: while developping, you often reload the same file.
18:02:37 pjb` Baggers: in the benign cases, the defpackage form has not changed, so hopefully it'll be idempotent. But you may have added or removed some external symbol, and added or removeed some packages from the use list, etc. Implementations are basically free to do whatever then want with the new definition. Most try to do something sane, but there may be conflicts. Most try to provide useful restarts, but they're not standardized, and the
18:02:37 pjb` debugging UI is not specified.
18:02:40 Baggers pjb`: true, but I dont see how this would differ from when using defpackage normally. Or is that your point, that defpackage in general has this issue (whether using macros or now)
18:02:46 pjb` And it's interactive!
18:02:54 pjb` It doesn't. :-)
18:03:32 pjb` But since defpackage is problematic, when you define your own macro it's better to give it a definite semantics, by using the functions instead of the defpackage macro.
18:03:33 Baggers pjb`: cool! so I'm at just as much risk now. It is really good to know though, thanks
18:04:00 kenanb pjb`: but in case of a real structure object, it can be left uninitialized, in case of list/vector structures I see two possible exits: either it will be initialized to nil (or the specified vector element-type in case of vector structure type), or it may as well error on initialization because a structure of type vector/list is being created with slots that cannot be initialized, now I wonder if both of them are permitted, or if it
18:04:00 kenanb will always initialize to a default-default when structure is of type list/vector
18:04:43 kenanb will do more careful reading of spec now
18:04:49 pjb` Well, make-array doesn't specify a default default element either, and while make-list has nil, defstruct could call it with a different initial-value.
18:09:54 Shinmera Baggers: You can tell it to, by using a custom template
18:10:04 Shinmera Baggers: Sorry for the late response, was out eating dinner and all that
18:11:39 Baggers Shinmera: no worries at all, I'm happy that it doesnt by default, good to know I can do this if needed though
18:11:57 Baggers Shinmera: I'm enjoying documentation-utils too, thanks for that
18:12:31 Shinmera Baggers: Sure thing
18:12:55 Shinmera Baggers: All the actual behaviour and look of the generated template is in https://github.com/Shinmera/staple/blob/master/default.ctml
18:13:03 Shinmera Baggers: So you can write your own if you want it to look differently
18:14:25 Baggers ace
18:26:05 kenanb pjb`: yeah, what leaves me confused is that spec states the behaviour as undefined for reading such slot of an instance, which is ok for a structure class, but when it is a list or a vector, it implicitly means that "all slots should be initialized somehow FOR the object to be created", but should an object necessarily be created? an implementation may as well decide to default-default initialization for such slots to (error "No value
18:26:06 kenanb provided, no initform exists, a vector cannot be initialized.") as long as the spec doesn't state that "objects will always be created regardless of initialization of their slots and the behaviour is undefined ONLY when an attempt to read the slot is made."
18:27:55 kenanb pjb`: on the other hand it says that about default constructors: "It is as if the slot-initforms were used as initialization forms for the keyword parameters of the constructor function." which IMHO implies when no initform is explicitly specified, and when the keyword is not provided in initialization, it will default-default to nil, just as we expect with a normal function.
18:34:58 pjb` kenanb: well, if an implementation leaves places uninitialized (eg. with safety 0), reading the car of a cons cell used to not store such an uninitialized slot value could indeed get you an random bit pattern and this could be interpreted by lisp as anything or nothing. It could crash your system, it could give you access to the "kernel", it could be any lisp object or something foreign, it could indeed be the address of the device tha
18:34:58 pjb` launches nuclear weapon upon your city, and dereferencing it would trigger WWIII.
18:35:08 pjb` So just don't do it!
18:35:25 pjb` And for more safety, always write slot-initforms.
18:36:52 pjb` kenanb: it's not what it says. It says that the constructor may use (&key (slot nil slotp)) (when slotp (setf (struct-slot struct) slot)) and when not slotp, nothing is stored. So assuming struct was allocated with a low-level, efficient, non-initializing allocator, you're framed.
18:37:01 phoe_krk Even if the initforms are just plain errors.
18:38:51 pjb` Well, actually the spec says: (cond (slotp (setf (struct-slot struct) slot)) (slot-initform-p (setf (struct-slot struct) (funcall slot-initform-closure)))) so you can indeed use (defstruct s (x (error ":x is mandatory")))
18:46:50 kenanb of course I can do that, what I wonder is if the implementation is free to do that as a default-default, or should an implementation either not default to anything, or default to a value (and not a condition)
18:47:01 marsjaninzmarsa ** NICK Marsjan
18:47:13 Marsjan ** NICK marsjaninzmarsa
18:49:04 kenanb anyway, I guess in practice an implementation will always default to something that fits (and vector-element-type slot-type) or slot-type or nil.
18:51:08 kenanb pjb`: I understand and agree with your points, thanks god I was not considering not providing initforms as a practice, I was more curious of what happens on the edge cases.
18:52:47 kenanb spec usually not only states what happens but also what the implications of the specified and unspecified behaviour are. for structures IMHO it does the second slightly less so, yet still pretty comprehensive in general.
18:53:23 kenanb pjb`: thank you for the very detailed answers, as always :)
19:00:52 pjb` kenanb: some implementations, like sbcl or ccl specifically do not initialize arrays to nil when you don't give an initial-element.
19:01:07 phoe_krk sbcl inits them to zeroes.
19:02:31 kenanb hmm
19:04:13 sweater ** NICK Guest17398
19:05:31 kenanb oh wow
19:05:48 pjb` It should be noted that the unix kernels allocates pages by making them point to a 0-filled page with COW. So when you allocate big memory blocks, you get it filled of 0s. But once you've garbage collected things right and left, you could very well allocate new blocks on old data including references that have already been garbage collected, or not.
19:06:30 Bike it's 0, or 0.0, or #\Nul, or #c(0.0 0.0), or...
19:06:36 pjb` Reviving old data would be bad for the garbage collector, so there's insentive for the implementations to reset it. But it could merely have a flag in the array to indicate that it doesn't contain any reference.
19:08:25 pjb` So you could try to make an argument from the garbage collector point of view (which may read your arrays for GC purposes), but since the GC is not specified, it's not even sure you've got one, so the argument doesn't stand.
19:38:50 phoe_krk pjb`: is it intended for your reader not to include UNQUOTE and BACKQUOTE functions?
19:50:13 pjb` phoe_krk: basically, yes.
19:50:44 pjb` I could provide a default implementation, but most of the time you would want a different implementation.
19:52:54 pjb` If you post an issue on one of git.framasoft.org, gitlab, or github, I might implement it, but I won't have time to start working on it before Q4.
19:55:31 circ-user-2glXF how does one create a secure, temporary directory in a common lisp program?
19:56:37 attila_lendvai circ-user-2glXF: IIRC, UIOP has something (it's part of ASDF)
20:00:57 circ-user-2glXF the temporary directory functions in UIOP seem to just return "/tmp", which already exists
20:03:48 phoe_krk pjb: Q4?
20:04:21 Shinmera Fourth quarter of the year
20:05:27 phoe_krk Got it.
20:05:35 PuercoPop circ-user-2glXF: SBCL has sb-posix:mkdtemp
20:07:50 circ-user-2glXF PuercoPop: thanks, just what I need
20:11:15 circ-user-2glXF looks like osicat-posix has it too, which is even better
20:26:56 pjb` circ-user-2glXF: one does not. You can create one that is probabilistically safe enough to use, or you can rely on the underlying OS to provide one.
20:37:12 Jonsky hello, is there any way I can set the repl to go back to the top level automatically after displaying the error message?
20:38:03 Jonsky I reckon that I usually just :a instead of using backtrace
20:38:28 jackdaniel maybe (ignore-errors …) ?
20:40:51 Jonsky jackdaniel: thanks
20:43:21 jackdaniel yw :)
21:27:10 sweater ** NICK Guest55567
21:28:24 pjb` Jonsky: or you can implement your own repl: (defun repl () (loop (handler-case (print (eval (read))) (error (err) (terpri)(princ err)(terpri)))))
21:28:51 pjb` cf. com.informatimago.common-lisp.interactive.interactive:repl