From: Andy Wingo <wingo@pobox.com>
To: "Maciek Godek" <pstrychuj@gmail.com>
Cc: guile-user@gnu.org
Subject: Re: Me no understand scoping
Date: Sat, 09 Aug 2008 13:05:58 +0200 [thread overview]
Message-ID: <m3k5eqcusp.fsf@pobox.com> (raw)
In-Reply-To: <e2ceda030808021436q7f96762oa91e89db4821bc48@mail.gmail.com> (Maciek Godek's message of "Sat, 2 Aug 2008 23:36:24 +0200")
Hi Maciek,
On Sat 02 Aug 2008 23:36, "Maciek Godek" <pstrychuj@gmail.com> writes:
> [Neil]
>> 1. IMO this could be really beautifully done in GOOPS, by defining
>> custom metaclasses and slot types.
>
> I've been considering that, and I'm still having doubts.
> The main reason is that there's no documented way
> of accessing GOOPS objects from C (except from using
> scm_c_eval_string etc.), or at least I couldn't find any
> documentation for that.
You can use scm_slot_ref et al. See goops.h.
> Besides (which is the matter of personal taste), I don't
> like the idea of using generics and trashing the global
> namespace with them. (I mean, the sole idea of generics
> is fine, but I wouldn't want to be forced to use them)
[...]
> I'm really trying to get close
> to the classical OOP notation: object.method() -- and
> it's probably why I explore the potential of using these
> "poor man's objects"
I wrote about this notational issue a while back on my blog,
http://wingolog.org/; I'm offline at the moment, so unfortunately I
don't have a link. Search for "slot-ref". I think with-accessors is an
elegant solution to this problem.
> But the point is that I saw that there is a 'make-hash-table' function
> available in lisp -- and this lead me to the conclusion that it's probably
> because the scopes/closures/environments implicitly use hash
> tables to store their bindings (and the same mechanism was given
> explicitly to the programmer).
This is false. Consider the closure:
(let ((val 0))
(lambda ()
(set! val (1+ val))
val))
Lexical scoping + closures was one of the fundamental ideas of scheme.
You can analyze this code /lexically/ to determine that we only need to
allocate storage for one variable. Wherever you see `val' in the body of
the lambda, you know /lexically/ that you are referring to a location
that is one step out in the stack frame, and the 0th location in that
frame, the frame created by `let'. So there is no need to store the
name, "val", at all!
By way of illustration, look at this disassembly of that closure in
guile-vm:
scheme@(guile-user)> (let ((val 0)) (lambda () (set! val (1+ val)) val))
$1 = #<program b6fbf388>
scheme@(guile-user)> ,x $1
Disassembly of #<program b6fbf388>:
nargs = 0 nrest = 0 nlocs = 0 nexts = 0
Bytecode:
0 (late-variable-ref 0)
2 (external-ref 0)
4 (call 1)
6 (external-set 0)
8 (external-ref 0)
10 (return)
Objects:
0 ((guile-user) . 1+)
Externals:
0 0
Sources:
6 #(1 36 #f)
8 #(1 26 #f)
The external shown there, "0 0" refers exactly to the outer stack frame,
the zeroeth location. The external-ref and external-set instructions
manipulate that storage location /by index and not by name/.
Do you see now why local-eval can't possibly work in the presence of
efficient compilation? Scheme does not give you the particular kind of
dynamism that you want. There is no hash table lurking inside a closure.
On the other hand, modules do have hash tables, and modules are
evaluation environments; and they have been treated in some literature
as closures. Perhaps consider using modules as your first-class objects?
> And so I never stopped to believe that (define x 5) is more or
> less equivalent to (hash-set! global-scope 'x 5).
At the top level it is; but s/global-scope/the current module/.
But internal defines are completely different.
Happy hacking,
Andy
--
http://wingolog.org/
next prev parent reply other threads:[~2008-08-09 11:05 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-07-29 21:18 Me no understand scoping Maciek Godek
2008-07-30 3:24 ` Clinton Ebadi
2008-07-30 8:42 ` Maciek Godek
2008-07-30 14:03 ` Jon Wilson
2008-07-30 15:04 ` Klaus Schilling
2008-07-30 19:24 ` Maciek Godek
2008-07-31 7:20 ` Neil Jerram
2008-07-31 19:21 ` Maciek Godek
2008-07-31 21:37 ` Neil Jerram
2008-07-31 23:07 ` Maciek Godek
2008-08-02 17:43 ` Neil Jerram
2008-08-02 21:36 ` Maciek Godek
2008-08-08 20:54 ` Neil Jerram
2008-08-10 21:49 ` Maciek Godek
2008-08-09 11:05 ` Andy Wingo [this message]
2008-08-10 22:30 ` Maciek Godek
2008-09-11 14:56 ` JonWilson
2008-07-31 23:48 ` Clinton Ebadi
2008-08-01 22:00 ` Maciek Godek
2008-08-02 5:13 ` Jon Wilson
2008-08-02 21:35 ` Maciek Godek
[not found] <cmu-lmtpd-29005-1217434291-0@mail-imap1.uio.no>
2008-07-30 16:18 ` Kjetil S. Matheussen
2008-07-30 19:03 ` Clinton Ebadi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m3k5eqcusp.fsf@pobox.com \
--to=wingo@pobox.com \
--cc=guile-user@gnu.org \
--cc=pstrychuj@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).