freenode/#lisp - IRC Chatlog
Search
17:14:27
jcowan
can anyone talk about practical examples of degenerate arrays, either of rank 0 or of no elements?
17:25:15
jcowan
I was actually thinking of multidimensional arrays rather than vectors of size 0; I see the application of the latter well enough, as they are a particular instance of empty indexable sequences
17:26:13
ggole
Once you allow empty arrays of rank 1, it would be inconsistent to disallow empty arrays of higher rank.
17:29:25
pjb
jcowan: (aref #0A42) #| --> 42 |# can be used as a generalization of scalar in a context where you are processing arrays.
17:33:44
pjb
yes, http://www.lispworks.com/documentation/HyperSpec/Body/22_c.htm says that format CREATES and returns a string containing the output.
17:35:47
sjl
Yeah, it would have been nice if they had just said "fresh string" in the FORMAT section itself.
17:36:41
pjb
(make-array '(2 2) :initial-contents '((1 2) (3 4))) #| --> #2A((1 2) (3 4)) |# is mutable.
17:37:58
sjl
If by "immutable" you mean "the consequences are undefined if you mutate it" sure, but that's not what jcowan means.
17:49:42
LdBeth
Immutable array is stupid idea, there are bunches of more efficient immutable data structures to use
17:51:24
jcowan
I meant immutable in Henry Baker's sense: an exception is thrown if you try to mutate it.
17:55:52
ggole
In general you need updates to data structures, and copying the whole array is too slow
17:57:07
ggole
For persistent arrays tou can do structure-sharing stuff with wide nodes to do better than that, but that's not 'immutable arrays' in the sense that you seem to mean
17:59:51
jcowan
"Immutable vectors of non-characters can be extremely useful as lookup tables, which can be passed in toto without worrying about the callee side-effecting the table." --HB
18:02:43
jcowan
immutable objects are also good in distributed computing, which is one of HB's central concerns.
18:10:58
jcowan
I tried to remove mutable strings from Scheme, where strings are sui generis (not arrays), but failed to convince the committee to break the IEEE standard
18:12:55
pjb
Nothing prevents an implementation to provide them. The verbiage of the specifications clearly allows it.
18:13:30
void_pointer
One of the hard things is that assuming one has managed to get all of one's data into a valid state in the first place, is keeping it from becoming invalid. I've had times where an array was the best structure for something but it was something that should not change at all after creation (it was intercoupled with some other things that shouldn't change).
18:13:40
heisig
Truly immutable data structures always sound nice on paper - until you have an application where performance and storage matter a lot.
18:16:35
void_pointer
It is a fairly common situation to have 2D or 3D arrays that should never change once initialized when doing various scientific and engineering simulations. Though to be fair, it isn't exactly common for the people doing such simulations to worry about this or many other problems, for better or worse.
18:21:30
_death
or (defmethod (setf gref) ((array immutable-array) &rest subscripts) (thats-a-no-no))
18:23:13
void_pointer
Or if you can control where it gets stored in memory and have the right permissions, just put it in some pages of memory by itself and then set those pages to read-only so that a fault is raised any time there is a write to the pages assuming you have a processor that supports that.
18:24:16
_death
sure.. and how useful is this feature in practice? in Lisp, we usually document whether the function is destructive or not
18:26:48
void_pointer
It would depend on how mission critical whatever the code is doing is. I don't think common lisp is used for very many mission critical things where great lengths should be gone to to make sure that an invalid state cannot be entered and/or it at least fails gracefully.
18:28:40
void_pointer
You know, an interesting question. Is anybody doing mission critical stuff with lisps these days? I sometimes wonder
18:29:29
_death
void_pointer: language features are often severely overrated when it comes to "mission critical" code.. in practice, it's process and the environment external to the system that matters there
18:31:06
void_pointer
_death: that makes sense. One tool in the toolchest among many. Insufficient by itself
18:35:04
_death
a language isn't any good if the implementation's quality is unknown.. so code has to be written with full knowledge of the latter
18:36:25
_death
but the processes involve actual effort into testing, designing with redundancy and killswitches in mind
18:37:59
void_pointer
Yes, and ideally plain old simple electronic and mechancial failsafes if applicable.
18:49:48
wiselord
hey! Please help me, i need an example for condition with auto-restart for the case: i run function (startn-fn () (ProcessingLoop () ... (getFromWeb ...) )), getFromWeb calls drakma:http-request, and if drakma:http-request (in fuction getFromWeb) return error (usocket:ns-try-again-condition) - i need atomatically restart (restartPL () ...). For manual restart i use code (start-fn () (restart-case
18:51:39
shka_
wiselord: well, ok, try that http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html
18:52:36
shka_
*handler-bind section explains how to establish restart and invoke-restart with examples included
18:54:27
wiselord
but examples in book for local exceptions, and in my case the signal comes from the usocket package
19:01:08
jcowan
Note that lambdas are mutable or immutable according to whether a set! modifying variables local to the lambda is lexically apparent or not
19:07:29
shka_
makomo: you will need such thing only when defining macro that defines macro that contains macrolet ;-)
19:10:21
francogrex
before when I had a 32 bit I was using cl-win32ole library to read and create MS excel and word documents and it was great https://github.com/quek/cl-win32ole/tree/master
19:10:54
jcowan
shka_: Lexical environments are only mutable if there is a lexically apparent setq that mutates them, that's my point. And the compiler knows that.
19:11:26
francogrex
however recently i decided to finally build the 64 bit CL implementation version and use it, however does any one know if there is a library to interact with COM?
19:41:31
jcowan
I've decided to switch from macros that expand to definitions to macros that expand to their bodies. More verbose but much clearer.
19:53:09
jcowan
That seems orthogonal to my point, which is not to hide definitions inside macro invocations.
20:01:37
phoe
jcowan: I only expand to DEF* and DEFINE-* macros inside macros that are defining macros themselves.
20:04:28
jcowan
Here I am doing something like `(defun variant-function (foo bar) (variant-generator 'this 'that foo bar)`
20:04:53
jcowan
obviously it could generate the defun as well, but that makes the function definition un-apparent.
20:20:41
jcowan
_death: I do, but the multiple (variant) functions are two-liners now instead of whatever the size of variant-generator is
20:22:11
jcowan
phoe: And yes, I do need a toplevel function for each variant, because I don't control the API
21:42:11
jcowan
I don't think, given the desire to find the definition of function foo in a large codebase, would go searching for "(setf (fdefinition 'foo".
21:42:57
aeth
No, but I don't assume that functions are defined by defun, I assume they're defined by defun or define-*
21:43:15
jcowan
ACTION grumbles at the irregular definition of -, which means one thing for one argument and something totally different for 2+ arguments
21:43:17
aeth
Maybe I'm the only one who likes to write macros that write defuns rather than writing defuns directly for a lot of things (e.g. shaders)
21:43:38
aeth
If you have a pattern that creates a function, it would be reasonable to turn it into a macro called define-*
21:43:55
phoe
jcowan: I wouldn't search the codebase, I'd do M-. in slime and let it find the source for me
21:46:18
aeth
If I see a define-* in CL I assume it ultimately creates at least one of (1) a function, (2) a macro, (3) a standard-object, (4) a structure-object, or (5) a type. Unless it does something fancier like sets a value in a global hash table or something... but that probably should be replaced with a function that returns one value IMO.
21:51:08
aeth
(defmacro define-function-from-lambda (name lambda) `(progn (setf (fdefinition ',name) ,lambda) ',name)) (42+ 1) => 43
21:57:34
no-defun-allowed
it takes a string (might make it a downcased symbol later) and two lambdas and sets it in a hash-table
22:00:01
aeth
What I do instead of relying on an implicit global hash table is that I have an explicit function that takes in a list of symbols and does something with that. So e.g. define-shader defines a function that returns a shader object and define-shader-data contains a lists all of the shader objects. So defining a shader is a pure function with no side effects, but you have to define which shader-returning functions to actually use
22:01:16
aeth
Like this: https://gitlab.com/zombie-raptor/zombie-raptor/blob/8a028d9f2ecbdf1a4abe1912677e143ea9219aff/examples/shaders.lisp#L126-141
22:01:25
no-defun-allowed
they're only used internally and can only be named and found with #'find-codec so purity isn't a big problem for me
22:02:01
no-defun-allowed
so when my parser hits an atom `base64:AAAA` it funcalls (find-codec "base64" :decode) with "AAAA"
22:04:54
aeth
no-defun-allowed: You could probably replace that with a with-codec macro that binds the function to a variable so it's not looked up every time.
22:18:42
aeth
oni-on-ion: I can't tell when the CCL log bot isn't here, I just know that it usually cuts off around that point
22:19:42
oni-on-ion
ahh =) yeah. wasnt sure if your client may have truncated. this client here (weechat) automatically splits up a certain amount into seperate messages
22:20:39
aeth
It depends on the server and the size of the total IRC message (which includes some metadata like your nick) afaik. I get several more characters to work with than you.
2:54:58
ealfonso`
I want to mock a function like drakma:http-request within a unit test. Can I use flet? It seems that the scope of my flet binding is lexical, can I make it dynamic?
2:58:58
ealfonso`
does this gist mean I would have to implement it myself? https://gist.github.com/jasom/04606c9e418aee6f969c8b1fdf69ba68
3:04:12
oni-on-ion
ah ty! i was scrolling up feeling certain i seen something else in use #here very recently
3:06:14
beach
ealfonso`: Yes, there is no standard way of creating a function with dynamic extent. If you do it with a macro that changes the FDEFINITION, then make sure you have an UNWIND-PROTECT that sets it back.
3:13:52
loke
oni-on-ion: Also note that you really don't want to be running more than one thread while doing that trick.
3:16:03
loke
oni-on-ion: You can implement it by having a single constant replaced version of the function in question, and you setf the fdefinition of it in the beginning. Then, inside that function you check a thread-local binding of a variable that indicates which version you want and if it's unset, just forward the call to the real (original) version.
3:18:44
loke
I just remembered I did something similar in Climaxima when I want to change the behaviour of some internal Maxima functions
4:08:51
beach
DecimPrime: Though, people here are less likely to read that book than they are to read books like PAIP, AMOP etc., since this channel is dedicated to Common Lisp.
4:14:30
DecimPrime
beach: hah. ahh i see. i'm mostly using clojure but i just heard it was great for learning how to break down and solve problems so i'm going to look through it
4:16:19
beach
DecimPrime: And I am guessing the advocate a more "pure" style of programming, like more functional programming, more recursion, etc.
4:16:59
beach
The Common Lisp books are typically more pragmatic. And modern Common Lisp uses object-oriented programming (using CLOS) a lot.