scicloj / wolframite

An interface between Clojure and Wolfram Language (the language of Mathematica)
Eclipse Public License 2.0
46 stars 2 forks source link

More powerful aliasing (perhaps as an extended wolfram.clj) #59

Closed light-matters closed 18 hours ago

light-matters commented 4 days ago

Currently, simple function aliasing (1->1 swaps) can be added at runtime by passing the aliases either to the 'init!' function or to a given 'eval'.

More powerful aliases (Such as the experimental fn aliases explored in #58) would also be useful though.

This poses a problem however, as using the generated wolfram.clj namespace for wolframite-only aliases would potentially be confusing. One option would be to generate two wolfram.clj-like namespaces. One for the default wolfram definitions and functions (already adapted to map complicated things like Minus and Subtract) and one that extends this namespace with a series of UX-enhancing aliases. This could have plausibly useful defaults, but could also be extended by the user.

An example of simple aliases that would help usability and readability.

{
   '<-> 'ReplaceAll
   '** 'Power

'**2 'WolframitePower2
   '**3 'WolframitePower3
   '**4 'WolframitePower4
   '**5 'WolframitePower5
   '**6 'WolframitePower6
   '**7 'WolframitePower7
   '**8 'WolframitePower8
   '**9 'WolframitePower9

   '**-1 'WolframitePowerMinus1
   '**-2 'WolframitePowerMinus2
   '**-3 'WolframitePowerMinus3
   '**-4 'WolframitePowerMinus4
   '**-5 'WolframitePowerMinus5
   '**-6 'WolframitePowerMinus6
   '**-7 'WolframitePowerMinus7
   '**-8 'WolframitePowerMinus8
   '**-9 'WolframitePowerMinus9}

A really interesting usecase however, would be to take advantage of clojure's native unicode support and so greatly expand the number of symbols that could be inserted and processed directly.

Some examples could be the greek and hebrew alphabets as well as things like

   '⮾ 'NonCommutativeMultiply
   '√ 'Sqrt
   '∫ 'Integrate

.

This could greatly help the usability and readability of mathematical working.

holyjak commented 3 days ago

Users can already use write-ns! to generate their own "wolfram.clj". What we could do to address this need, is to allow them to include their custom "smart" aliases in the process. WDYT?

We'd also need to think some more about what exactly a "smart alias" is. I it a function? From what to what? The one we user internally is args -> symbol. Is that enough? Too limiting? Would it be better to send in a context which may contain args when processing the head of a list, and possibly in the future also other elements, as users share their needs.... Or we could leverage other traditional extensibility mechanisms, such as multimethods. We need to understand much better the concrete needs and the options we have.

PS: Notice that users could leverage the fact that wolframite.base.convert/convert is a multimethod and that "the last loaded impl. wins" and add their own version in their code, required after Wolframite's:

(ns my-data-project.core
  (:require [wolframite.base.convert :as w-convert]))
;; Override the one from Wolframite
(defmethod w-convert/convert :expr [[head & tail :as _cexpr] opts]
   (cond 
     (= head '**2) do-something...
     :else the-original-convert-expr-body...))

Of course they would need to use it in its symbolic form in expressions, as in (wl/eval '(**2 3)). The second part of this feature request addresses that, so that they could get their own wolfram ns and do st. like (wl/eval (my-data-project.wolfram/**2 3)). We still need to think about how that could be best supported. (A crafty user could call our write-ns! and then just append a snippet of code based on what we do for their aliases... Not very convenient, but certainly possible, and not too hard either.)

light-matters commented 2 days ago

All good points. I think allowing for crafty users is something of a killer feature of this project as I get excited about the possibility of not just having access to Wolfram but a customizable Wolfram! - Maybe we should put this in our marketing points :).

I would go a step further though (in the sense of having at least three layers: simple wolfram, extended (default) wolfram, and 'crafty'/craftable wolfram) as I do think that good customs should be available in a curated space that can be grown by a community and not just individuals. In this sense I'm thinking of spacemacs/doom vs vanilla emacs: almost noone in their right mind would use uncustomized emacs and it shouldn't be for individuals to have to reinvent the square wheel every time.