Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Semantics of define differs between the clojure macros and the metacircular interpreter #52

Closed
jar398 opened this issue Sep 17, 2018 · 1 comment
Labels
bug Describes a software defect. medium priority An issue we should address after the urgent issues have been taken care of.

Comments

@jar398
Copy link
Contributor

jar398 commented Sep 17, 2018

Here is a bit of technical debt to pay off some time. I don't think this is likely to bite anyone soon, but eventually it will, so I wanted to record the issue.

The issue is that the clojure-metaprob block macro (with its define keyword) only approximates what python-metaprob did, using the primitives available in clojure (let and letfn). The python-metaprob equivalent was internal definitions written using =, which augments the lexical environment by mutation. But the meta-circular interpreter is faithful to python-metaprob. This leads to differences in behavior, for example:

> (define loser 
    (gen []
      (define bar 13)
      (define foo (gen [] bar))
      (define bar 17)
      (foo)))
#'metaprob.examples.all/loser
> (loser)
13
> (infer :procedure loser :output-trace? true)
[17 {} 0]

The block/define macro is pretty hairy, and creates its illusion of environment modification by segmenting the sequence of definitions into let bindings and letfn bindings - very different from creating an environment up front and mutating it with each succeeding define.

I'm not sure what to recommend regarding a fix. Implementing the python-metaprob semantics in clojure would be extremely painful and would create implementation and documentation complexity far in excess of its utility. But implementing the block macro's semantics in the metacircular interpreter will also be difficult (albeit much less so). A third alternative would be to abandon block/define in favor of clojure let and letfn, with changes to the meta-circular interpreter to implement the clojure syntax.

@jar398 jar398 added the bug Describes a software defect. label Sep 17, 2018
@zane zane added the medium priority An issue we should address after the urgent issues have been taken care of. label Jan 25, 2019
@zane
Copy link
Collaborator

zane commented Apr 1, 2019

Fixed by #123.

@zane zane closed this as completed Apr 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Describes a software defect. medium priority An issue we should address after the urgent issues have been taken care of.
Projects
None yet
Development

No branches or pull requests

2 participants