GithubHelp home page GithubHelp logo

kredati / ludus-namespace Goto Github PK

View Code? Open in Web Editor NEW
0.0 1.0 0.0 93 KB

A hacky experimental javascript reification of namespaces; or: a functional `with`

License: GNU General Public License v3.0

JavaScript 100.00%

ludus-namespace's Introduction

Reified namespaces in Javascript

Please don't use this

It's with, but with functions and more hacks

The basic idea (& excusing my perverse preference for snake_case):

import {ns, using} from '@kredati/namespace'

const my_namespace = ns(
    {foo: () => 'bar', quux: () => 'baz'},
    {id: x => x},
) //-> {foo: ..., quux: ..., id: ..., [Symbol('namespace')]: true}
// "namespaces" all normal keys of all objects
// no duplicate keys are allowed, and it will only allow object literals

const my_function = () => id(foo())

my_function() //-> throws ReferenceError: id is not defined

using(my_namespace, my_function) //-> 'bar'
using(my_namespace, () => quux()) //-> 'baz'
using(my_namespace, () => __namespace__) //-> my_namespace

As I said, don't use this.

using uses what is effectively a stupid version of a macro to do this, although it's nowhere near as sophisticated as anything in, say, sweetjs or, uh, a real lisp. It's reasonably robust, however, since the transformation is so simple.

The namespace/ns function ensures there are no duplicate properties on namespace objects. using will only accept a "safe" namespace object that has been built by the ns function. And, for every property on that object, it adds a const variable declaration & definition before executing the passed function inside a newly-constructed lexical scope. Because of this, it follows normal lexical scoping rules for const and let: everything in the namespace can be shadowed to no ill effect. Pass-by-reference values (objects, arrays, &c.) can, of course, be mutated.

To do all this, it uses the Function constructor, the toString method of the passed function, and some very simple template strings.

Unlike with, namespaces can be modified, returned, and accessed, using the __namespace__ variable inside the function.

using executes the passed function immediately and passes through its return value.

Why would you want to do this? Well, you don't. It might be useful at a repl, maybe? (How?) The only real use case I can think of for something like this would be to automate the bootstrapping of environments for early learners of a language. And even then it's a disaster because it explodes linters and stack traces and line numbers. (Better off programmatically manipulating the global context until you learn them what they need to handle scope & imports.)

But if you do want to? Well, with is not possible in es6 modules (for good reason!), so this stands as a substitute. It's an experiment, to see how hard it would be to do. (It was easy!) It arose as a thing I wanted to try as part of an ongoing project to see how hard you have to push JS to get really lisp-ish behavior and constructs. See, e.g., this essay. Perhaps it is one step closer to Clojure's first-class namespaces, a discussion of which is what got this idea in my head.

Not that it's earth-shattering--but ultimately this stands as an iteration of the (relative) power of the way JS represents functions, especially including its toString method. Code really is data! And can be transformed, reasonably easily. (So long as the code is inside a function. And doesn't violate JS's parsing rules. &c...)

ludus-namespace's People

Contributors

kredati avatar

Watchers

 avatar

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.