Code Monkey home page Code Monkey logo

Comments (14)

sritchie avatar sritchie commented on May 30, 2024 2

What was I thinking, not using transducers??

(let [render (comp ->infix simplify)
      series (((exp (* 'h D)) tan) 0)]
  (render
   (transduce (take 10) + series)))

from sicmutils.

sritchie avatar sritchie commented on May 30, 2024 1

Ah, @kloimhardt what I meant was that:

  • the initial push involved gathering together existing strands of thought / abstraction that should have lived together in the first place, like, making sure all of the number types implemented generics before the symbol types, and not mixing all that stuff up....

  • and further, those namespaces were where all of the interop with the JVM lived too, so that took a bunch of work to get the Clojure/Clojurescript versions working the same way.

  • But LATER, once that was in place, and @littleredcomputer's namespaces started learning on all of the generic operators, then I could go namespace by namespace and everything mostly Just Worked. The things that had to change in this middle phase were mostly tiny, like property access from (.items x) to (.-items x). This was a joy.

Keep asking anything you like, please! These are all good prompts for me to write up the experience.

from sicmutils.

sritchie avatar sritchie commented on May 30, 2024 1

#35 - for starting with those... I did NOT understand where they fit in at the beginning, I just chose those two because they had no further dependencies :) With the numerical types, like Complex, Fraction / Ratio etc I had to understand more about how the dispatch in numbers and numsymb was working, since some of those functions were trying to apply simplifications inside their bodies that didn't need to happen.

But later, porting the FDG stuff, for example, or the rational function and polynomial types, I stopped trying to understand and told myself I'd learn later :)

#36 - it totally might be... I can't remember where I found this. There is some CLJS reference describing using symbols like function, number, default... but object probably would accomplish the same thing.

About ratio?, don't be embarrassed, I was doing the same thing!! I changed it to the current method once I decided that I would have to implement an actual rational data type, and knew I'd need some spot to put the check.

**js-arity**

I actually did understand the JVM version, but it didn't help me write the Clojurescript version. The clojurescript version as written now, btw, is busted in advanced compilation mode, and I'm not sure it's possible to fix.

All that really mattered was understanding what the tests were trying to achieve, and how they were dealing with edge cases like assuming one of the arities was a sign of comp, etc... also I realized that the JVM version doesn't have a way of handling :between cases now, even though CLJS does. (I also don't know where / if that matters later. All of the tests certainly still pass!)

About why... I wrote to @littleredcomputer after working on the textbook (exercises here https://github.com/sritchie/sicm) for quite a while in the original scheme. Next I built an animation layer, and used sicmutils for that: https://github.com/sritchie/maturin then wrote to Colin with the idea of trying to get CLJS online so we could get the same animations running in the browser. Colin was super helpful, but I went down the rabbit hole pretty solo for a while after getting his blessing.

About Complex, I wrapped this library: https://github.com/infusion/Complex.js/ and was thrilled to discover that js/BigInt existed, so used that. This was my target for ratios https://github.com/infusion/Fraction.js/, specifically the bigfraction stuff inside. That required a number of PRs to cljsjs...

I used SCI because I THINK that cljs-eval will only work in the browser if you're in self-hosted Clojurescript, and I wanted folks to be able to use this thing as a library in their own apps, even in advanced compilation mode, without worrying about that. (But I could be wrong here and would love to hear that!!)

from sicmutils.

sritchie avatar sritchie commented on May 30, 2024 1

@kloimhardt , closing this for now but please feel free to write again!

from sicmutils.

sritchie avatar sritchie commented on May 30, 2024

Indeed it does, @kloimhardt ! I am gearing up for a major documentation push to go with this new release, where @littleredcomputer and I document the goods here... but SICMUtils does indeed have AD.

You can see a description of the system in @littleredcomputer 's "Physics in Clojure" talk here: https://youtu.be/7PoajCqNKpg?t=1386

And then a wild demo at https://youtu.be/7PoajCqNKpg?t=2297, where @littleredcomputer shows off this trick where, with AD, an expression like e^{h D} (D is the derivative operator) makes sense:

(let [render (comp ->infix simplify)]
  (->> (((exp (* 'h D)) tan) 0)
       (take 10)
       (reduce +)
       (render)))
;;=> "62/2835 h⁹ + 17/315 h⁷ + 2/15 h⁵ + 1/3 h³ + h"

@kloimhardt , let me know if you have any more questions, or want to kick the tires here.

from sicmutils.

kloimhardt avatar kloimhardt commented on May 30, 2024

@sritchie , thank you, exited to see sicmutils evolving, especially the cljs port (started myself a year ago). Concerning AD, I allowed myself to add a comment to the according Clojureverse entry.

from sicmutils.

sritchie avatar sritchie commented on May 30, 2024

nice @kloimhardt ! Werkbank looks awesome. The port was a heavy lift... hopefully it will come in handy. My next step is to get it added to Maria.cloud so folks can play with it live in the browser.

from sicmutils.

kloimhardt avatar kloimhardt commented on May 30, 2024

Indeed heavy, your lift, @sritchie . I naturally wonder which angle you approached the cljs-port from, how did you start? Lessons learned from porting clj to cljs would be a topic for a conference talk in itself (or blog post?), did not find any such desperately sought after guidance. Hopefully cljs helps that people will start to play with sicmutils. (I could not convince tutors to move away from Mathematica at my local University, but I am sure that was just because the barrier of installing the JVM was too high :-) .

from sicmutils.

sritchie avatar sritchie commented on May 30, 2024

@kloimhardt the high barrier was what motivated me too, and I hope you're right that the browser interface makes this all easier. I also agree that I should write up this process, and I will!

I sequenced everything via PRs, so if you want to see the gory details, here's the list of all... oh my god, 82 PRs!

https://github.com/littleredcomputer/sicmutils/pulls?q=is%3Apr+author%3Asritchie

I started with standalone namespaces, like the pattern stuff: #35

And pretty quickly realized I was going to have to figure out how to make generic arithmetic work in Clojurescript. This took a few tries:

etc... After that it was fairly smooth sailing, until I hit the numerical routines and went into turbo mode getting all of that converted. That was weeks of reading old textbooks and papers, but at that point I had to finish since I knew it would all work, and couldn't quit without the ability to do browser animations.

I'll write up more on this for sure. Thanks for the nudge!

from sicmutils.

kloimhardt avatar kloimhardt commented on May 30, 2024

The PR's are really a treasure trove. So you moved namespace by namespace. My wrong strategy was: Start in clj with an example (* 3 4). Then, still in clj, mock out clj code in several namespaces that is not relevant for this example. Then, having this clj skeleton, convert to cljs. Upshot for me is: the tests written by Colin were crucial for you, (right?? @sritchie). If this impression is correct, one important message to the Clojure Community is that without the tests, this cljs port would have been impossible in practice.

from sicmutils.

sritchie avatar sritchie commented on May 30, 2024

Oh, yeah, it would have been completely impossible without @littleredcomputer 's test suite. I added many more tests as I went too, to tease out distinctions between Clojure and Clojurescript.

I was able to do this less and less as I moved on, since the foundational namespaces (numeric implementations, anything that hit the JVM) were the only places that required serious attention.

I did have to do some work moving things around to consolidate that foundation! But once I got past that it became easy to go namespace by namespace and lean hard on the tests.

from sicmutils.

kloimhardt avatar kloimhardt commented on May 30, 2024

By "I was able to do this less and less" you mean "I was less and less able to do this moving namespace by namespace strategy", right @sritchie ? That means a very interesting part of your journey lies in the tale: "Necessary transformations of existing clj code I should have done in the first place".

from sicmutils.

kloimhardt avatar kloimhardt commented on May 30, 2024

Concerning PR #35
@sritchie How did you make the decision to start with match.clj and rule.clj? For me the major issue was not knowing where to start best.
Did you understand, at this time, from a mathematical/algorithmic point of view what match.clj and rule.clj are used for, what their purpose is in sicmutils? In other words: is it necessary to understand the algorithms when doing a clj->cljs port?

PR #36
value.clj line 61: why extend-type #?(:clj Object :cljs default) and not extend-type #?(:clj Object :cljs object). I used object but was not sure whether that's the right thing to do.

#?(:cljs (def ^:private ratio? (constantly false))) is a clever move, as you explain in the comment: "this lets us keep the code untouched, and gives us a hook for later". I am embarrassed to admit that I was commenting out the #_(ratio? o) call in the definition for exact? Lessond learned: do not touch existing code! there is always some other way (remember: adding functions do no harm).

The function js-arity seems to be a good example of this in Clojureworld so scorned test.driven development. Am I correct that you did not try to understand jvm-arity at all and just fulfilled the arity tests with js-arity?

A general question:
@sritchie , how long before the first PR did you start prototyping/ thinking of the code? How long before did you contact @littleredcomputer with this idea? The general rule here seems to be: do not port without the support of the original author.

PR #37
lesson learned: reader conditionals do not work within macros, https://github.com/cgrand/macrovich to the rescue!

PR #41 #43 #46
I understand now that those namespaces had heavy Java interop and were in need of clean abstractions. Those had to be put in place as cljs conversion went along.
Is it correct that you introduced Complex Numbers and Arbitrary Precision Integers to Javascript here?

Looking at the last PR's , I think it is important to tell the world that babashka's SCI works in Clojurescript as well. But what made you use it as opposed to cljs-eval? In my bb-web project, I use SCI because of the superior error messages.

from sicmutils.

kloimhardt avatar kloimhardt commented on May 30, 2024

I have no insight on cljs.js/eval-str. Had short conversation with cljspad though. SCI is a blessing here.

from sicmutils.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.