freenode/#lisp - IRC Chatlog
Search
12:34:42
jmercouris
I saw this stack overflow answer: https://stackoverflow.com/questions/578290/common-lisp-equivalent-to-c-enums
12:36:35
jmercouris
is a function call significant overhead as compared to simply having a constant?
12:37:12
jmercouris
I ask because I'm hesitant to use a constant, as the implmentation may change, that data may end up being stored in a database rather than in a configuration file, or in the source code
12:41:14
phoe
jmercouris: you could define a pure function that accepts an argument and returns constant numbers
12:41:21
LdBeth
jmercouris: what do you want to do with enum? I think most of the time plain symbols just work
12:41:23
Bike
not that a function call is THAT expensive. but it will be more expensive. given that the operation of the function will be to look up a constant?
12:42:14
phoe
this will inline the constant and then allow the compiler to optimize the number into raw assembly
12:43:07
phoe
if you then need to change the implementation, declare the function notinline, recompile your whole codebase, replace the function body with something that e.g. fetches data from database and returns the same numbers
12:43:54
phoe
but the question is, do you absolutely need numbers in there? maybe keywords can be enough
12:47:47
schweers
The question is also: how often will this function be called? If it’s not in a tight loop my guess would be that you don`t have to worry about it.
12:48:16
schweers
Even if you need it in a tight loop, just bind a variable outside (it’s supposed to be constant anyway, right?)
14:31:49
aeth
The StackOverflow answer seems mostly correct, except for using symbols instead of keywords, which the top comment addresses. Obviously, you might need to use the number-based more-enumlike solution in some cases (FFI, databases, network, etc.) in which case I usually just name constants. They can still be namespaced with separate packages.
14:32:45
aeth
Sometimes I use structs with typed slots or with array backing, which won't be as efficient since there's a runtime lookup, but they should still be pretty efficient. And with with-accessors, you don't really notice they're accessors, not variables.
19:37:41
cosimone
hello everyone, basic newb question: i am currently reading about the CLOS for the first time, and apparently, it looks like defstruct is still in the language for the sake of backwards compatibility
19:38:06
cosimone
are there stil valid use cases for defstruct even in current code, or can i just go ahead and use defclass all the time?
19:38:38
Bike_
defstruct can be more efficient sometimes, but you should basically always use defclass.
19:39:40
Bike
if you like defstruct's automatic symbol choices you could use a macro around defclass.
19:39:41
TMA
solrize: there are things like defclass* / define-class libraries that provide the conveniences of defstruct
19:40:26
cosimone
from what i've seen, isn't providing an :accessor symbol to a slot enough to get nicer reader-writer functions?
19:40:44
TMA
cosimone: there are use cases (like treating lists/arrays as structures) that defclass does not provide
19:40:50
cosimone
hell, it seems even better than the default structname-slotname names generated by defstruct
19:41:23
solrize
i really should read a clos tutorial sometime. i looked at it once and went this is too complicated
19:41:26
Bike
solrize is saying that sometimes having to specify all the :accessors and stuff can be repetitive.
19:42:14
jasom
CL has several pairs that are static/fast and dynamic/not as fast; structures and classes are one of these
19:42:27
cosimone
i agree though, that defstruct looks more "compact" if you don't need anything fancy
19:43:12
jasom
unless you know that the overhead of classes will cause problems, I don't see a reason to use structures
19:43:49
cosimone
at first glance, i'd just use classes by default and then change to structs if absolutely necessary for performance
19:44:19
cosimone
honestly, worrying about stuff like this early seems like a textbook example of premature optimization
19:45:11
dlowe
also, you will hate it if you ever want to add or remove a field to a struct without restarting
19:46:32
cosimone
does any of you have an example where structs could be preferred for reasons other than pure performance?
19:47:32
dlowe
if you had a theoretical lisp implementation that didn't support the metaobject protocol, you could use a list-based struct to iterate over its contents.
19:47:40
jasom
cosimone: the only thing I can think of is that it communicates to the reader that the type is limited to the features that structures have.
19:51:02
jasom
cosimone: that's a bit of a weak reason, fwiw. Also I use structures most of the time because of habit.
20:01:03
cosimone
jasom: i mean, i can understand why. at first glance, it seems like a reasonable choice if you aren't using methods
20:01:14
aeth
structs are useful when the :type in slots is useful because they give the compiler a lot more room for optimization. So if you're storing a single-float or an array of single-floats, you'll (in a properly optimized implementation) get faster accessors and save yourself a bunch of type declarations.
20:02:52
aeth
In practice, if you wanted to use :type in defclass slots, well, you shouldn't, because implementations can freely ignore it, and the most popular implementation (SBCL) does ignore it on default optimization levels so the vast majority of your users won't ever get type checking. You'd have to use the MOP to ensure types get checked.
20:04:28
aeth
So I guess some people with heavily typed slots might use structs even if not for performance, especially if they mainly care about type checking in SBCL, where structs will get their slots typechecked but standard objects won't.
20:05:24
aeth
But that's not really a good reason because that's just an SBCL-first development approach when you can just portably use the MOP
20:07:00
aeth
Most of CL's weaknesses in general revolve around when you *don't* want to be generic. Basically the anti-Go.
20:10:06
aeth
But, anyway, what you then wind up with is basically a split, and one of the few actual uses of defstruct. If you want to reliably check slot types, use a metaclass in defclass to ensure that e.g. ":checked-type" is always checked via an assert. If you want an implementation to be able to optimize based on provided slot types, use defstruct.
20:15:21
fiveop
To what magic stream does compile send its output? (sbcl) https://pastebin.com/bZDt5cAi
20:16:43
dlowe
There's a lot of them http://www.lispworks.com/documentation/HyperSpec/Body/v_debug_.htm#STquery-ioST
20:19:18
fiveop
I don't actually want to get at that output necessarily. I really want to get the actual style-warning object.
20:22:21
Bike
of course that aborts the compilation. you can use handler-bind if you don't want to do that.
20:25:25
fiveop
I get the output (which going by src/compiler/ir1report.lisp should go to *error-output*) and it returns <function> nil nil
20:27:53
fiveop
It did not help that just (compile nil (lambda (a b c) a)) gives almost the same result and output as does the quoted version