sci

https://github.com/babashka/SCI - also see #babashka and #nbb
borkdude 2020-07-29T07:07:21.335700Z

Logseq is using sci, they seem to be inspired by Roam: https://github.com/borkdude/sci/commit/56bbf5187ae95c8b58a065623a2b960bc7561d70

2020-07-29T10:46:46.337300Z

Is there a way to have “private” functions in Sci? I found that when I’m writing Sci macros I’m forced to expose more functions than I want. Does this sound familiar?

borkdude 2020-07-29T10:50:26.337500Z

Would be most clear with an example

2020-07-29T10:52:04.338100Z

i was affraid so 😅 I’ll try to compile something simple

borkdude 2020-07-29T10:52:45.338700Z

btw, because of your comment I noticed that bb and sci don't care about private 😂

$ bb '(ns foo) (defn- foo []) (ns bar (:require foo)) (foo/foo)'

2020-07-29T10:57:40.339Z

haha

2020-07-29T10:58:05.339600Z

clojure doesn’t care to much about private vars either (#'some-private-var)

2020-07-29T10:59:14.340600Z

Below is a contrived example of a case where I use a macro. I want to expose view-of to the Sci environment. Ideally only this macro would be available but that doesn’t work. I need to expose view-of* as well or the macro generates code that the interpreter doesn’t understand. Now the view-of* function can also be called directly.

(defn view-of* [ctx label some-value]
  (internal-function-here some-value)


(def view-of
  ^:sci/macro
  (fn [_&form _&env & body]
    `(the-exposed-ns/view-of* (pr-str ~body) (do ~@body))))

2020-07-29T10:59:49.341400Z

another confusing thing is that ` doesn’t work as expected. You need to know where the view-of is mapped to

borkdude 2020-07-29T11:00:02.341900Z

Yeah, that's how macros work. Any code that they generate could also have been typed in by the user.

2020-07-29T11:00:02.342Z

I’m not saying Sci should fix this. Just another level of complexity

2020-07-29T11:00:28.342400Z

Yeah I guess you are right

borkdude 2020-07-29T11:01:06.343Z

What I usually do here is end the function name with -impl to indicate that it's not something you should call directly.

2020-07-29T11:01:44.343600Z

yeah makes sense. In another case I’m using a specific namespace for the implementation

2020-07-29T11:02:04.343900Z

good to know i’m not crazy. Thanks 🙂

👍 1
tiensonqin 2020-07-29T13:36:02.346100Z

> Logseq is using sci, they seem to be inspired by Roam @borkdude Yes, Roam is a huge inspiration for logseq, logseq will not be a outliner and the graph view without Roam! I'll just copy some text I replied to the Athens community yesterday here: User privacy is an essential thing for Logseq. We believe user's notes should be stored locally, the server will never store user's private notes, and we do provide publishing so that you can publish on Logseq, in the future, you can publish it to any platforms like Github pages or netlify. It can sync your notes using Git, Github is supported now, more options (Custom hosted Git service, Dropbox, WebDAV, etc.) are in the roadmap. Currently, logseq already have most features similar to Roam Research (huge inspiration) like outliner editor, block(and page) references and embeds, graph visualization, we also have directly hiccup support and a live Clojure Interpreter which is using https://github.com/borkdude/sci. You can also specify any datascript queries (to filter blocks, pages, tags or anything in the datascript db), you can also specify a custom view component for any queries (using hiccup). Another big difference between logseq and other tools (including Roam) is that logseq work directly with the plain text (markdown, org mode, etc.), if you're familiar with Obsidian, logseq is something like a web Obsidian with Roam's killer features like the outliner and block embeds. I've been using logseq for organizing my notes and todos for two months (it works on mobile too), but I think it's still early days, some users from the logseq discord group reported some bugs like file corrupts. So please don't use it for serious writings now. Logseq draws a lot of great ideas from Roam (outliner, backlinks, sidebar), Emacs org mode (heading properties, todo keywords, priorities), and Tiddlywiki (transclusions, contents, and lists), hats off to all of them!

👍 1
😯 1
ikitommi 2020-07-29T13:49:21.346900Z

(= int? (sci.core/eval-string "(comp (comp int?))"))
; => true
👍👍👍

2020-07-29T15:05:17.348Z

Is there a way to access :line and :column information outside of exception conditions?

borkdude 2020-07-30T09:30:53.354800Z

> And I think the implementation for what I need would look similar. So you would only need the line and symbol from the latest invoked function right? So something like (first @sci.core/callstack) which would give {:var foo/bar :line 1 :column 10}?

2020-07-30T12:23:36.355Z

Yes I think that would be enough. it would need to be the function that is currently being invoked, not after it has been invoked

borkdude 2020-07-30T12:24:37.355200Z

well, the currently invoked function would be the one on top of the stack

👌 1
borkdude 2020-07-30T12:25:06.355400Z

anyway, I'll poke you when I have this done so you can test it for your purposes

2020-07-30T12:30:04.355700Z

Thanks!

2020-07-29T15:10:27.348300Z

I’m using sci to render reagent components and valid sci code is causing invalid reagent results. I would like to use the line and column information to provide feedback for the user. I’m not able to get it from the sci context AFAIK

2020-07-29T15:12:55.348500Z

If I could get access via a dynamic var like sci/*current-line* that would work for me. Does this make sense?

2020-07-29T15:30:42.348700Z

I guess a function would make more sense as it would not give overhead for cases where this is not being used

2020-07-29T15:35:31.348900Z

Maybe related to being able to control iteration / have a custom step function https://github.com/borkdude/sci/issues/348

borkdude 2020-07-29T17:17:12.349500Z

line and column information is available as metadata on forms and symbols

2020-07-29T19:28:13.349700Z

I don’t think this would allow to do something like the below, right?

`(sci/eval-string "(foo :hello)"
                  {:bindings {'foo (fn [] 
                                    (println "foo is being evaluated from line "(:line (sci/get-context)) ))}})

borkdude 2020-07-29T19:29:45.349900Z

Maybe there is. Let me check

borkdude 2020-07-29T19:36:25.350100Z

Don't think so yes. But this ties a bit into another issue I'm solving at the moment, where I keep around a callstack of called functions in the interpreter. Would that help somehow here as well?

2020-07-29T20:18:09.350400Z

Maybe if the current symbol/function would be in the callstack and available via some kind of API. Then I would be able to save it in the context where the error might occur in the future

2020-07-29T20:19:28.350600Z

I’ll think about it a bit and maybe hack it into Sci to see how it could work exactly

borkdude 2020-07-29T21:06:20.350800Z

This branch has a work in progress callstack: https://github.com/borkdude/sci/tree/borkdude/babashka%23508. The callstack is accessible in with @sci.impl.vars/callstack. It's currently implementation detail because I don't know exactly yet how things are going to look. This is a fix to a wrong file name location reported with babashka (see issue 508).

borkdude 2020-07-29T21:07:03.351Z

But I was thinking this would also be useful in babashka/sci errors in general, to print the interpreter callstack with locations.

2020-07-29T21:19:45.351300Z

Looks useful indeed! And I think the implementation for what I need would look similar. I would mostly need :line and :column to print a nice error. (I’ve copied Figwheels error reporting approach to have an intuitive error)

2020-07-29T21:32:28.351600Z

I use it like this now. Lots of room for improvement still, but it’s already super handy