Oh, and that’s the other thing I was going to say: tools trump language. Much as I love Clojure, we would have had some serious domestic arguments by now were it not for Emacs, the REPL, parenthesis-based editing, specifications, and so on. (It’s still not great for multi-file projects.) Java coding was enjoyable because Eclipse is so amazing - though that could be a trap obscuring OOP pitfalls. The norns web interface is a good solid piece of work: as sophisticated as it needs to be to do the job well, and no more.

1 Like

part of my motivation in having norns use lua is that i wanted something that could be potentially as approachable as teletype (ie, for non-programmers) but also powerful enough to do more complex things.

so, on one end of the spectrum— i wanted someone to be able to have a half-page of code which sets up softcut in a particular way, maps some encoders or midi, and shows something musically helpful on the screen. maybe extend it with some tables for musical purposes… ie, everyone has their own sequencer. at this level the code functions more like a composition, in a sense.

but i also set a precedent for big complicated scripts that are more like tools and less like compositions (ie mlr). and these big scripts could possibly use some OOP effectively. but to be honest i’m rewriting mlr from scratch and still not bothering with OOP— it feels overkill.

but where it is more often needed is in the core libraries. so maybe this is a good moment to set out a request: from all the smart people in this thread, we’d happily welcome contributions to the core library. for example— when norns started, there was no concept of “parameters” and that grew over time. i’d like to find situations where the core libs can address basic recurring needs, so where possible user scripts can be as short as possible and leverage existing patterns.

that said, things like the param system don’t accommodate every need— and there’s a point where overbuilding that system has diminishing returns. it’s very easy to make a custom param-menu-like thing… because it’s lua.

ps. the scripting docs (particularly the libs) are in desperate need of an overhaul, and a vision towards it. which will likely also suggest some sort of syntax unification… which is maybe what is meant by house style.

9 Likes

I think this kind of cookbook approach can really work & agree having off the shelf library components makes the creative lift of new ideas much easier

While not in anyway claiming to be “a smart person” - My Kria port has got a new output module which makes midi/crow output easier to shove into a script - I’d like to see how it goes down with people but if I get a positive response will submit it for consideration

4 Likes

Lua is indeed a good fit here - relatively simple out-of-the-box, but with the flexibility to be exploratory without being verbose. Sam Aaron went for Ruby with Sonic Pi for a similar reason, I think, though the simplicity there is a bit more syntactic: play 60 and you’re away.

Regarding the core library… well, FWIW shado is now up and running, though it needs a bunch of example apps and a push on the documentation. I’m not sure it’s quite ready to ship as a built-in component until it’s been stress-tested for performance.

1 Like

There’s been a couple mentions of functional programming here, and I’m a fan of it too. It’d be nice to see some development of FP in the core library. Maybe developing the core lib deserves its on thread. Would be good to get some input on a couple things I want to contribute there.

4 Likes

This looks fun, but it’s LuaJIT only. In any case, without efficient immutable data structures I’m not sure it gets you very far.

This may be of interest: I just came across https://github.com/Tieske/Penlight, which includes some functional programming idiom support.

1 Like

last year we had a long conversation about adding penlight… and luarocks in general.

main takeaway was: with luarocks, we’d have a hard time adding yet another project management layer so that community scripts could all work.

penlight has some nice features, but also some incredibly heavy ones… which could introduce quite a lot of confusion and complexity. so we sortof punted, opting not to get into it. @zebra @ngwese

i suppose we could re-open that inquiry, keeping in mind that most of us have focused areas of the code we’re already working on.

Yeah… where to draw the line. Penlight looks impressive, but also quite heavy, and part of the appeal of norns for me is that it’s carrying a payload which does what’s needed to provide an integrated environment and nothing more - it’s lean.

3 Likes

Agree. The question that needs to be asked is ‘what problem are we solving?”

The ‘issues’ I have had are: clock sync/link - now solved, can’t be bothered writing things over & over - mostly output - I have my own solution for that. I also wondered today if some thing like teletypes faders & buttons might make sense? Params could do dynamic updating for slightly nicer UX

And that’s about it. Don’t need a lot else. All that is Norns specific too

1 Like

Especially while nothing’s really stopping a script author from pulling in penlight to their script if they’d really like its features :man_shrugging:

1 Like

Adding stuff to the base software stack is much easier than removing it so there has naturally been a healthy amount of debate around adding dependencies like penlight or even leveraging luarocks. I look at stuff like penlight and think:

  • is this something we want to carry forever as a dependency?
  • does it promote / foster implementations that are liable to work well in the embedded lua environment which matron provides?
  • does it provide something which cannot be achieved easily or by other means?
  • is it something that helps or hinders someone new to the platform or to coding?
  • is it something which helps or hinders one’s ability to share scripts among the community?
  • is there any risk that adding the dependency could increase support load on the core collection of folks fostering the platform today.

I’ve personally gone back and forth on this several times while debating myself. In the end I usually found myself coming back to:

penlight to me looks like a mixed bag, some good, some not so good. The higher order functions are the few things that I could see myself using but those are also readily had with passing functions/closures into existing iteration mechanisms. I’m generally a fan of functional programming but I also expect/want a solid immutable collection library to go with it and an optimizing compiler to eliminate all of the intermediate garbage when using it in an environment which is soft real time.

Of late there has been more energy around building/expanding the core library in ways which are broadly applicable across the types of scripts people are generating.

All that said I do occasionally install stuff locally just to try it out and experiment (or pull it into the lib/ space for whatever script I’m working on). For code/scripts which one doesn’t intend to share there is little downside.

2 Likes

Ah, the MIT disease of incorporating every feature and option. Perhaps we should be thankful that the norns cannot (yet) function as an email client.

The lowest-impact route for new code is is probably to keep letting people roll stuff out as top-level script libraries. Scripts can refer to one another, and the main loadable script can serve as a demo. (The script downloader doesn’t do dependency analysis, but taking that task on probably means, well, reimplementing luarocks.)

3 Likes

This is a bit of an aside, but: as a very minor feature upgrade, would there be any support for something like .gitignore for sub-directories of scripts? I want to roll out a script which itself scans a subdirectory for other scripts, none of which is directly runnable. Right now everything appears.

Alternatively - house style? - should everything actually be somewhere under lib? As I think about it, I’m not averse to lib/something for “internal” coding, so may just refactor to that.

How have others approached saving “instances” of objects in their norns scripts? tabutil.save doesn’t save the metatables. Could I use tabutil.load and then set the metatable of the loaded table?

There’s probably a better way to do it, but what I’ve basically done is to have my class constructor take a table of options that set all of its properties. When I save it, I use tab.save, and when I load it, I pass the loaded table to the constructor again and overwrite my instance with a new one.

Sounds convoluted as I type it, but hopefully makes sense…

sort of like:

local instance = MyObject.new(options)

tab.save(instance, path)

local loaded = tab.load(path)

instance = MyObject.new(loaded)

1 Like

Both the matron menu system code and maiden share an implicit agreement that “runnable” scripts are anything *.lua that appears just below the script/project dir which is not below lib/.

If you have lots of code which isn’t directly runnable I’d recommend adding structure under lib/. I do this quite regularly and it is the strategy in use by many of the more complex scripts.

2 Likes

Makes sense, will do - thanks.

also, ‘data’ and ‘docs’ will not be scanned by menu

2 Likes

makes sense: permissive languages go hand-in-hand with Slightly More Testing (but type-safe/immutable languages aren’t necessarily non-tests-required).

I am interested in this thread, primarily as a programmer, but also seeing what peoples’ perceptions of paradigms and patterns are, as well as their understanding of them. It varies dependent on prior experience, skill level, culture, and many other things, and that’s useful stuff to process.

My 2p:

  • “house style” is at best advisory unless you have either good tooling (eg a linter or formatter or both), or a language where there’s One Way To Do It (eg Python).
  • without Magic Tools (and languages that easily support them) making sure that a few Good Examples already exist is always helpful.
  • (as @cassiel points out, the maiden UI is one such tool, thumbsup; at the very least, new coders have access to a UI with formatting and such.)
  • strongly agree with “the most straightforward thing to write is a list of imperative actions”. I like that we have a REPL, on device, that does things; I like that you can bang out the ugliest script that Works For You, because it’s a machine to make art, not ecommerce stores. And then, if you want more structure/tidiness, it is available in a variety of ways
  • as long as the internal libraries are consistent, that’s a good start. any behaviour/patterns enforced there will probably trickle down a bit.

I’m always interested in watching OOP/functional arguments because it takes me a while to cotton on to what people are really advocating for/complaining about. So: I’m largely an OOP programmer at heart (and by trade), but when I say that, I’m saying it as a Rubyist, and my OOP is… smalltalky? Objects are lightweight, easily defined and modified, heavy emphasis on methods-on-things, and introspection, and duck typing, and not just “hashes which can contain functions”? I see people complaining about OOP but then I realise they’re mainly complaining about Java, and sure, I hate Java too, and the way it pushes everything into Classes and Factories and whatever. I possibly might only like Ruby-style oop.

Similarly, I still can’t quite tell if, when advocating for “a more functional approach” people mean “just functions as first-class-objects I can pass around so I can be more functional if I’d like to”, like the ecmascripts… or “more top-level functions”, like Python and Lua… or if they really think everybody should be writing Haskell. Again, I like the permissiveness to do the first, which lets you write in the style of the last if you really want… but making the latter the only way just seems unfriendly to most new coders.

I feel like I’m just derailing now, but have been thinking about this thread for a bit, and so now dropping those thoughts in.

3 Likes