freenode/#lisp - IRC Chatlog
Search
10:00:50
xificurC
(funcall 'foo 2 3) generates the same assembly as (funcall #'foo 2 3), seeming the fdefinition of FOO is compiled in as a fixed memory location. I thought 'foo would be compiled as a runtime lookup. If one wanted runtime lookup one would need to use symbol-function?
10:31:03
xificurC
loke: where does lexical scoping come into play here? FOO is special and flet should rebind it dynamically. The way I see it right now is that BAR is calling the previously defined FOO no matter what
10:32:49
loke
However, the following works, because #' looks up the function definition in the lexical scope:
10:34:01
xificurC
loke: I always imagined I can interchange value and function lookup, i.e. (let ((foo 1)) foo) to work the same way as (flet ((foo () nil)) (funcall 'foo))
10:35:22
loke
xificurC: Note that you pass the _symbol_ foo to funcall. It's FUNCALL that looks at the symbol and decides which function to call. Funcall isn't in the same lexical scope, so there is no way it could ever see your local definition.
10:35:44
_death
although it's interesting that the funcall entry says "symbol" instead of "function name"
10:37:02
_death
(of course this contradicts my statement, and only symbols are dealt with that way..)
10:37:46
xificurC
clhs even states for noobs like me "Within the function definitions, local function names that match those being defined refer to functions or macros defined outside the flet"
11:12:52
jmercouris
I'm going through gentle introduction to symbolic computation, and I am stuck on this problem: https://imgur.com/a/rTOIRR1
11:13:19
jmercouris
I understand why the example given is wrong, but I cannot think of how to solve the second part
11:19:38
jmercouris
schweers: it doesn't say that, but it simply says "as a combination of ANDs and ORs that does not fail"
11:20:01
jmercouris
I'm going through the book, imagining that I do not know things not yet introduced
11:20:19
schweers
okay, then we may assume that both frue-part and false-part are only one form (I hope)
11:20:33
makomo
does this alternative definition of IF have to return the actual value of the true-part, or can it just return t?
11:26:00
makomo
so it seems like this alternative definition is only good at selecting the right operation
11:33:50
jmercouris
because if the first clause returns t it will jump to the second block and return "t"
11:34:38
jmercouris
also in my first message, I did not mean to say "you'll never hit the second t block", I should have said, "you'll never get the evaluation result"
11:38:56
jackdaniel
little late on the party, but: (or (or (oddp 3) 'foo) (and (oddp 3) (evenp 7))) ; if we are willing to evaluate test twice in worst case
11:40:01
jackdaniel
so either (or (or TEST FALSE) (and TEST TRUE)) or (or (or TEST FALSE :nothing) TRUE)
11:51:34
jmercouris
I can't imagine how intimidated a new CS student would feel going through this book
11:54:11
makomo
there's a certain math textbook with lots of math exercises but *NO* solutions at all
11:54:22
makomo
the rationale is that "a mathematician should get used to the unavailability of solutions"
11:54:30
jmercouris
I already took software design classes in my undergraduate, and those were oftentimes ambiguous on purpose. I think the goal is to teach lisp, not generalized software engineering
11:54:55
jmercouris
there is a valuable lesson here, I just think this is the wrong book to teach it
11:56:21
makomo
_death: also, i think that the fact that side-effects can be ignored should be mentioned upfront, even if the book didn't get to side effects yet
11:57:32
_death
makomo: if they're actually reading the book they may notice that it's not yet introduced..
11:58:39
_death
that would get in the way of understanding for people who don't know what side-effects are, which forms a big part of that book's target audience, I'd think
11:58:45
makomo
instead of the book saying something like "ah remember that example? we didn't handle the problem of multiple evaluation then" later on
12:03:18
xificurC
so I'm not sure what the exact question is. But reading the discussions it was said the return value doesn't need to be kept. The last or isn't necessary but it is symmetric to the then part
12:18:49
jackdaniel
if block/return are allowed, then it is possible to return values too, otherwise I think it is not possible without null/not
12:19:29
xificurC
shrdlu68: given that I understood code blocks are only to be run for side effects that looks correct
12:21:00
shrdlu68
Unless there's a way to create NOT using AND and OR, I don't think this has a solution.
12:59:49
makomo
beach: and what if some of these before/after methods contain error checking that is not necessary within internal functions
13:00:17
makomo
and you want to avoid that extra work, since you know you're providing correct values as the implementor
13:01:17
makomo
i suppose the accessors are part of the external protocol? how do you name these internal accessors then?
13:02:20
beach
Not all accessor names are exported. The ones that aren't belong to some internal protocol.
13:05:11
makomo
beach: so in the case when you want to avoid error checking because hypothetically it might be expensive, do you have 2 accessors? a safe one which is part of the external protocol and an unsafe one which is part of the internal protocol?
13:05:38
makomo
i suppose the difference isn't that clear though, since you might offer safe and unsafe versions as part of the external protocol?
13:06:35
beach
makomo: Two options then. Either stick two accessors for the same slot and use some auxiliary methods only on the externally visible accessor. Or make the external generic function not an accessor and have its method(s) call generic functions in the internal protocol.
13:08:02
beach
makomo: I always work under the assumption that my stuff is fast enough, even with error checking. I design good data structures and algorithms to make that happen. So far, I have not had to make anything that is part of some external protocol "unsafe".
13:08:38
beach
makomo: I usually design the external protocol first, and I decide what I want it to do.
13:12:05
beach
makomo: Yeah, I rarely have to micro-optimize, and I always compile with speed 0, debug 3, compilation-speed 0, safety 3, space 0.
13:13:10
beach
makomo: Unless, of course my research is about highly optimized code, as in this one: http://metamodular.com/reverse-order.pdf
13:18:31
kuribas
why does compiling: (defun f (x y) (declare (type fixnum x y)) (+ x (* y 2))) give me: forced to do GENERIC-+ (cost 10) ; unable to do inline fixnum arithmetic (cost 2) because: ; The second argument is a (INTEGER -9223372036854775808 ; 9223372036854775806), not a FIXNUM.
13:22:16
Xach
SBCL (and possibly other implementations) will do efficient things with machine-word modular arithmetic.
13:22:56
makomo
are there any guarantees regarding the behavior of fixnums (such as overflow, etc.)?
13:23:27
Xach
if you declare something a fixnum and it is not that size, things are allowed to break.
13:25:48
shka
makomo: thing is, all those type declarations are geared mostly toward efficiency first, and type safety secondly at best
13:26:24
shka
so until you have program that works and is already debuged, you may prefer to skip manual type declarations
13:36:44
kuribas
So I understand correctly that there is no type which have the semantics of machine integers?
13:37:29
beach
jdz: Maybe in WSCL, I will be more strict about the meaning of type declarations, especially in safe code.
13:38:19
Bike
kuribas: but integers act like integers. semantics aren't determined by type in lisp. if you want arithmetic modulo whatever, you write the modulo yourself, and your compiler can try to lower that to machine arithmetic (sbcl does so)
13:40:48
beach
kuribas: Oh, it's safe if you carefully check for it each time. Now look at how many C programs assume that x + 1 > x.
13:40:49
_death
kuribas: what lack of performance? if you have speed 3 it's a shl and an add as it's supposed to be..
13:41:02
Bike
like old video games where you heal a bunch and end up with negative four million health
13:43:27
xificurC
kuribas: wrapping might be desired in *some* cases. It's not how the world works. Or do you suddenly have 0 apples when you buy 1 more but your basket is full
13:44:03
makomo
beach: in the case of signed integers, that is actually always true and could be optimized out by the compiler :-)
13:44:03
xificurC
if you want to write assembly or C, write assembly or C. Don't expect a high level language to magically generate the tightest code possible
13:44:48
makomo
there was a bug report on GCC's issue tracker where one guy was mad when GCC started making use of that optimization
13:44:52
_death
I don't understand why people suggest switching to a different language.. sbcl is sufficient here.. and if you still want more performance, just write your assembly routines in lisp :)
13:45:32
xificurC
_death: it feels natural when one is trying to get language X's behavior in language Y
13:46:38
beach
_death: You are right of course. But it seems kuribas is pouting because Common Lisp is not unsafe by default like other languages are.
13:47:06
_death
beach: I think kuribas did just that the other day as well.. and the answers were also similar
13:47:08
xificurC
shrdlu68: why are people under the impression writing good asm by hand isn't possible anymore? Make a few web searches
13:50:05
beach
_death: Oh, this one is a pearl: "<kuribas> I am not expecting anything in common lisp to be new or surprising..."
13:51:16
beach
And this: "<kuribas> you give up a large part of safety when programming in a dynamic language", especially given that kuribas now wants arithmetic to be unsafe by default.
13:52:56
jackdaniel
I think he means a compilation-time safety wrt types of function arguments. It can't be ignored as non-existent and CL indeed doesn't provide this kind of safety
13:54:22
_death
I don't see how modular arithmetic is unsafe.. it's just something you need to implement because + and * on integers use ordinary kindergarten arithmetic
13:55:57
jackdaniel
shrdlu68: type declarations give you nothing (they may be conformingly ignored), but you may do check-type. that gives you a runtime safety (you will be dropped in a debugger whne program runs and values of incorrect type are passed to the function)
13:56:06
beach
_death: And that is what so many programs in languages that use modular arithmetic seem to do, because I don't typically see any test for that situation each time I see an addition.
13:57:34
jdz
In missiles in general I've heard -- their justification being that the missile hits the target sooner than values get close to overflow values.
13:58:14
_death
beach: right.. but here the desideratum was modular arithmetic given ordinary arithmetic, not the other way around
13:58:33
jackdaniel
I've read about a bug found on a racket (namely a memory leak which lead to OOM after some time). racket was after expensive process of QA and other verifications
13:58:54
shrdlu68
jackdaniel: But your implemention can give guarantees, right? I mean, if an implementation does not ignore type declarations.
13:59:01
jackdaniel
so they have figured out what is a maximum memory usage taking into account this memory leak while racket is running (say max 30m) and they've added enough memory to the hardware
14:00:55
jackdaniel
shrdlu68: sure, that is possible, just as it is possible to have C compiler with some undefined behavior explicitly defined. either way, my point is that it gives you runtime safety, not compilation time, so it is somewhat weaker
14:01:51
jackdaniel
I'm not saying that this kind of safety is crucial for good applications or that it improves overall quality
14:01:58
White_Flame
kuribas: if your input numbers are declared or inferred to be, say, between 0 and 1000, then the output can be inferred to be between 0 and 3000, keeping it a fixnum
14:02:06
jdz
OK, today I've learned that I've been relying on type checking behaviour that's very specific to SBCL. I guess I'll have to use SBCL exclusively from now on, because I like this behaviour.
14:03:05
jdz
Yeah, I've been keeping my code SBCL/CCL agnostic, but it is getting harder as time passes by.
14:03:57
jdz
But I definitely remember CCL giving me errors when SBCL hasn't. Don't have a record of particular instances, though.
14:05:24
jackdaniel
example are :type declarations for slots, CCL given high enough safety enforced it when you were using accessors. I think SBCL started doing that recently too
14:21:29
specbot
Splicing in Modified BNF Syntax: http://www.lispworks.com/reference/HyperSpec/Body/01_daba.htm
14:24:52
makomo
a question regarding CLOS style -- do people differentiate between using :default-initargs and :initform? the difference is subtle and i haven't seen :default-initargs used that often
14:25:25
beach
You typically use :default-initargs in a subclass to initialize slots in the superclass.
14:26:33
beach
That way, the subclass does not care how the initarg is used. It could be to initialize a slot, or it could be caught by initialize-instance.
14:27:13
makomo
i.e. i'm defining a slot within some class for the first time and i have to choose between :default-initargs and :initform
14:28:28
makomo
i've seen it discussed in the CLOS book even, but the difference was artificial and served mainly to communicate intent (but i don't know how well it does that)
14:29:31
beach
If the library is well written, it only documents initargs and accessors, not the existence or not of slots.
14:30:13
beach
So, you then use :default-initargs in your subclass, simply because it is your only option if you want to use only publicly documented features of the library.
14:31:11
makomo
aha, since you have no knowledge of the superclass' slots and cannot duplicate the definition just to change the :initform
14:32:29
beach
makomo: Your questions (and your reactions to my answers) make me think that you will make fast progress, so I don't mind answering them.
14:33:12
beach
makomo: By the way, I can't remember whether I told you, the last Common Lisp HyperSpec reference about keyword arguments makes me think that an error should be signaled for you case.
14:35:18
specbot
Keyword Arguments in Generic Functions and Methods: http://www.lispworks.com/reference/HyperSpec/Body/07_fe.htm
14:37:14
Bike
what was the setup again? (defgeneric foo (&rest r)) (defmethod foo (&key c) ...) (foo :d ...)?
14:38:04
specbot
Congruent Lambda-lists for all Methods of a Generic Function: http://www.lispworks.com/reference/HyperSpec/Body/07_fd.htm
14:38:25
makomo
and as we said, case 4 shouldn't apply in this case, since the GF doesn't have a &key in its lambda list
15:22:45
xificurC
(let ((x '(1 2 3))) (check-type x ?)) to check if x is a list of numbers with unknown length
15:25:42
pjb
xificurC: (defun list-of-number-p (x) (and (com.informatimago.common-lisp.cesarum.list:proper-list-p x) (every (function numberp) x)))
15:26:04
makomo
pjb: what does it do? i just tried to use it like (check-type (name spec) symbol), where NAME is a reader function, and i'm getting warnings since CHECK-TYPE is expanding into (setf (name spec) ...)
15:28:35
_death
makomo: yes.. check-type sets up restarts that may modify place to have a value of the proper type
15:29:13
sjl
sure, use (alexandria:proper-list-p list) instead of listp if you want to enforce proper lists
15:29:37
pjb
Sometimes you want to implement your own I/O loop validating the type of the inputs (notably if you have to do some parsing or conversions), but in simplier cases, check-type is a great operator!
15:58:15
Xach
I like cerror and try to use it when I can. I didn't really think about it for a long time.
16:22:08
jeosol
I want to thank you and all the other guys who responded and helped with query regarding the Optimization Challenge I was participating in. I recently received notice (recently) that my initial results where accepted and I should send additional info
16:22:30
jeosol
this was a late notice because it was sent last month, and due to some mailing issue, i could respond.
16:23:19
jeosol
I'll need to get some AWS machines to run rest of the cases. Currently research how to replicate an initial EC2 because manual install is a pain. Not a cloud expert.
16:25:06
beach
Congratulations! Though I don't think I was of any direct help. At least, I can't find any trace in the logs that I was.
16:32:19
jeosol
I was getting the system to work in a stable fashion then, working with many threads, etc.
16:32:52
jeosol
I did actually get a lot of help initially with the folks at comp.lang.lisp before I got here, but that site got very toxic so I stopped going there, but still read the questions occasionally
16:35:14
kuribas
So I found out I can get similar performance as in haskell by using (unsigned-byte 56) instead of fixnum.
16:42:04
jackdaniel
is there a reason for that? also – where did you find my address? unless it is a virtual bottle…
17:21:29
ultimate_beginne
Would it be fair to say that C FFI is a lisp DSL for writing low-level operations? Woke up pondering the question.
17:31:47
ultimate_beginne
I guess I'm thinking along the lines of (defmacro low-level (...) (...dsl similar to loop macro but with keywords for pointers, volatile, restrict, etc...))
17:35:15
White_Flame
FFI gives you data access to low-level memory, and the ability to call low-level code. It doesn't let you write low-level operations directly
17:35:54
White_Flame
however, the native code Lisp compilers are written in Lisp, and can be extended
19:28:50
knobo
jackdaniel: does ecl garbage collect functions that is defined with a gensym as name?
19:30:08
knobo
jackdaniel: like this: (defmacro def () (let ((n (gensym))) `(defun ,n () (format nil "t"))))