GithubHelp home page GithubHelp logo

mlochbaum / bqn Goto Github PK

View Code? Open in Web Editor NEW
839.0 31.0 57.0 9.73 MB

An APL-like programming language. Self-hosted!

Home Page: https://mlochbaum.github.io/BQN/

License: ISC License

JavaScript 33.54% KakouneScript 35.41% AutoHotkey 19.76% Vim Script 11.29%
apl multidimensional-arrays compiler functional-programming immutable language bqn

bqn's Introduction

View this file with a real REPL here.

BQN: finally, an APL for your flying saucer

documentationspecificationtutorialsimplementationcommunity

Try it online below (arrow at the right for more samples and shift-enter to run), on this page, or in our chat. Use CBQN offline; details here.

Looking for a modern, powerful language centered on Ken Iverson's array programming paradigm? BQN now provides:

  • A simple, consistent, and stable array programming language
  • A low-dependency C implementation using bytecode compilation: installation
  • System functions for math, files, and I/O (including a C FFI)
  • Documentation with examples, visuals, explanations, and rationale for features
  • Libraries with interfaces for common file formats like JSON and CSV

BQN will provide:

  • State of the art array performance: CBQN beats the fastest array languages much of the time, but not always!
  • A standard system to install and use libraries and packages, and support for package managers

I think BQN is a good choice for learning and enjoying array programming, scripting, prototyping, and number crunching at a single-CPU scale. For some examples of BQN in action, this repository holds the dreaded self-hosted compiler and the friendlier markdown processor used to generate the site. See also awesome BQN repositories, examples on RosettaCode, or something else from the community page.

What kind of name is "BQN"?

It's three letters, that happen to match the capitals in "Big Questions Notation". You can pronounce it "bacon", but are advised to avoid this unless there's puns.

What's the language like?

BQN aims to remove irregular and burdensome aspects of the APL tradition, and put the great ideas on a firmer footing. It maintains many of the ideas that made APL\360 revolutionary in 1966:

It incorporates concepts developed over years of APL practice:

But it's redesigned from the ground up, with many features new to the array paradigm:

Not sold? See why BQN? for an outline of what all these features add up to in terms of programming power.

How do I work with the character set?

Right at the beginning, you can use the bar above the online REPL to enter BQN code: hover over a character to see a short description, and click to insert it into the editor. But you'll soon want to skip the clicking and use keyboard input. I type the special characters using a backslash escape, so that, for example, typing \ then z writes (the backslash character itself is not used by BQN). The online REPL supports this method out of the box, and the editor plugins include or link to ways to enable it for editors, browsers, shells, and so on.

The font comparison page shows several fonts that support BQN (including the one used on this site, BQN386). Most other monospace fonts are missing some BQN characters, such as double-struck letters 𝕨, 𝕩 and so on, which will cause these characters to be rendered with a fallback font and possibly have the wrong width or look inconsistent. The double-struck characters also require two bytes in UTF-16, which breaks rendering in some Windows terminals. Windows Terminal itself fixed this in 2023, and VS Code and wsl-terminal also support them with an appropriate font.

Where can I find BQN users?

Chat forum links below; either of the bold ones will open in a browser without much hassle if you just want to get on quickly. Further forum details here.

Discord Matrix …in Element
All rooms Invite #array:matrix.org Space
BQN room #bqn:matrix.org Room

Discord is a popular commercial chat client and Element is a similar UI for the open chat protocol Matrix. They're bridged together so that messages in one appear in the other. Most discussion happens on these (they're quite active), but see also the community page for activities and such in other places.

Also feel free to contact me personally via Github issues or with the email address shown in my Github profile.

How do I get started?

BQN's tutorials are intended as an introduction to array programming with BQN. They assume only knowledge of elementary mathematics, but will probably be hard to follow if you have no programming experience. BQN has a lot in common with dynamically-typed functional languages like Lisp, Julia, or Javascript, so knowledge of these languages will be particularly helpful. The tutorials end abruptly right now, so you'll have to switch to the documentation, which is less structured. The documentation has a quick start page which is a nice way to dive in.

If you're already an array programmer, you might start with the documentation right away, using the BQN-Dyalog APL or BQN-J dictionary as a quick reference where appropriate. Be aware of two key differences between BQN and existing array languages beyond just the changes of primitives—if these differences don't seem important to you then you don't understand them! BQN's based array model is different from both a flat array model like J and a nested one like APL2, Dyalog, or GNU APL in that it has true non-array values (plain numbers and characters) that are different from depth-0 scalars. BQN also uses syntactic roles rather than dynamic type to determine how values interact, that is, what's an argument or operand and so on. This system, along with lexical closures, means BQN fully supports Lisp-style functional programming.

A useful tool for both beginners and experienced users is BQNcrate, a searchable collection of BQN snippets to solve particular tasks. If you have a question about how you might approach a problem, give it a try by typing in a relevant keyword or two.

bqn's People

Contributors

adregan avatar alexdikelsky avatar andersontorres avatar andrewnc avatar andreypopp avatar ashermancinelli avatar bjterry avatar codereport avatar dancek avatar davidssmith avatar detegr avatar goranpjevic avatar humanequivalentunit avatar jshholland avatar mlochbaum avatar mysticalunicat avatar patrickmn avatar paulapatience avatar pkova avatar razetime avatar saltysylvi avatar sternenseemann avatar steveulin avatar suhr avatar thezjy avatar totallyuniquelily avatar vincent-carrier avatar xelxebar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bqn's Issues

3 √ 729 returns float not integer

Hello, I noticed the following when working on a documentation major mode for emacs. I'm unsure if its a bug, or intended due to some floating point standard.

Consider:

9 ⋆ 3

   729

But:

3 √ 729

   8.999999999999998

and

0‿1‿2‿3 √ 729‿729‿729‿729 

   ⟨ ∞ 729 27 8.999999999999998 ⟩

So sometimes returns a float even though 729 has a integer cube root.

The next lowest natural number that has both an integer square root and cube root is 64, notice that we get integers back rather than floats:

0‿1‿2‿3 √ 64‿64‿64‿64

   ⟨ ∞ 64 8 4 ⟩

For what its worth numpy only returns a floats, although offset in the opposite direction:

Python 3.8.2 (default, Feb 26 2020, 02:56:10)
>>> import numpy as np
>>> np.cbrt(8)
2.0
>>> np.cbrt(64)
4.0
>>> np.cbrt(729)
9.000000000000002

Installation confusion

I'm a little confused at how to get BQN up and running on Linux using CBQN, I don't know what I'm reading wrong or if there is something I'm missing. How am I supposed to get this up and running. I'm on WSL Ubuntu if that is any help. I'm am really interesting in this language and notational/array based syntax and semantics as a whole and any help would be greatly appreciated.

The example of `Switch` produces an error

Sorry for a noob question.
I tried Switch described on Control flow in BQN on REPL and CBQN:

Switch  {c⊑𝕩  ma<˘21𝕩  (⊑aC)◶m@}
value  "double"
v  33
Switchvalue
  "increment"  {𝕤 v+1}
  "decrement"  {𝕤 v-1}
  "double"     {𝕤 v×2}
  "halve"      {𝕤 v÷2}
⟩

and got the following error:

𝕨⊑𝕩: Index out of range

Switch ← {c←⊑𝕩 ⋄ m‿a←<˘⍉∘‿2⥊1↓𝕩 ⋄ (⊑a⊐C)◶m@}
                                  ^^^^^^^^

Switch ⟨value
^^^^^^

So something is wrong. I found this one seems to work (REPL):

Switch  {c⊑𝕩  ma<˘21𝕩  (⊑(m⊸⊐)<C)◶a@}

Is this OK?

Request for flashy examples in docs

Tutorials assume (pretty presumptively, really. Disgusting.) that you are already motivated to learn BQN and use simple rather than flashy examples. Documents to induce motivation beyond the README are not yet available.

I'm one of those people who is you know curious but cautious and I need to see bit of beauty to really dig in. Would love to see some wild examples. In particular, the slides in this section of Aaron Hsu's talk struck me and I'd like to learn them in BQN (I don't know APL)

image

VM docs for `+` don't mention monadic case

The runtime section of the VM docs mention that the + operator needs to work on two atoms, but I believe this should say "one or two atoms" just like - since the JS VM fails when the monadic case is not handled.

Explain the use of `under ​⌾` primitive in tutorial/variable.md

This is the paragraph where that primitive first appears in the tutorial:

So let's break this down. The 2-modifier Under (⌾) has two operands: the left one, -⟜1, subtracts one, and the right one, 2⊸⊑ uses a function we haven't seen before. It uses the right operand to pick out part of its argument, then the left one acts on that part only, and the entire argument, with the necessary modifications, is returned.

Online REPL lacks header support

When attempting to run the destructuring example from the docs on blocks:

    Destruct ← { 𝕊 a‿1‿⟨b,2⟩: a≍b }
    Destruct       5‿1‿⟨7,2⟩

The online REPL fails with the following error:

  Unknown character: :

Confusing Take error in REPL

In the online REPL, this code produces an error that just looks like nonsense.

3↑2‿2⥊↕4
×: Arguments must be numbers

CBQN produces this output:

   3↑2‿2⥊↕4
┌─     
╵ 0 1  
  2 3  
  0 0  
      ┘

Question about reshape

In APL I would write something like 3 4 ⍴ ⍳12 to get a 3x4 array of values from 1 - 12. In J it would be something like 3 4 $ i. 12 (which would give 0 - 11)

In BQN, I assumed it would work similarly 3 4 ⥊ ↕ 12 but I must be doing something incorrect. I have tried a number of blocking for presidence, but nothing quite works.

Anyway, I'd love to know what I'm missing. I'm loving bacon so far :)

Typo in bqnpad ceiling operator

image

hi just to say that there's a typo on bqnpad, don't know if this is the correct repo, nor how to fix it. so here's the fyi

Unexpected repl behaviour

I have encountered this behaviour a few times when using BQN. I will enter an expression, but instead of an output OR an error, I will see what seems to be a call graph.

For example,
{𝕩⍟0} 3 ->

v0=e[1];if(v0===null)err();
v1=e[5];if(v1===null)err();
v2=e[2];if(v2===null)err();
v0=call(v1,v0,v2);
v1={e:e,p:6};
v0=set(1,v1,v0);

v0=O[21];
v1={e:e,p:7};
v0=set(1,v1,v0);
v1={e:e,p:8};
v0=set(1,v1,v0);

v0=e[6];if(v0===null)err();
v1=O[21];
v2=e.p[66];if(v2===null)err();
v3=D[121](e);
if(v2.m!==2)err();v1=v2(v3,v1);
v0=call(v1,v0);

v0=e[1];if(v0===null)err();
v1={e:e,p:9};
v0=set(1,v1,v0);

v0=D[122](e);
v1={e:e,p:10};
v0=set(1,v1,v0);

v0=e[7];if(v0===null)err();
v1=e[10];if(v1===null)err();
v2=e.p[1];if(v2===null)err();
v3=e[4];if(v3===null)err();
v4=e[2];if(v4===null)err();
v2=((f,g,h)=>(x,w)=>call(g,call(h,x,w),has(f)?call(f,x,w):f))(v4,v3,v2);
if(v1.m!==1)err();v1=v1(v2);
v0=call(v1,v0);
v1={e:e,p:11};
v0=set(1,v1,v0);

v0=e[8];if(v0===null)err();
v1=e.p[55];if(v1===null)err();
v0=call(v1,v0);
v1=e[10];if(v1===null)err();
v2=e.p[1];if(v2===null)err();
v3=e.p[119];if(v3===null)err();
v4=e[4];if(v4===null)err();
if(v3.m!==1)err();v3=v3(v4);
v4=e[2];if(v4===null)err();
v2=((f,g,h)=>(x,w)=>call(g,call(h,x,w),has(f)?call(f,x,w):f))(v4,v3,v2);
if(v1.m!==1)err();v1=v1(v2);
v0=call(v1,v0);
v1={e:e,p:12};
v0=set(1,v1,v0);

v0=e[6];if(v0===null)err();
v1=O[21];
v2=e.p[66];if(v2===null)err();
v3=e.p[3];if(v3===null)err();
v4=e[11];if(v4===null)err();
v5=e[12];if(v5===null)err();
v4=list([v4,v5]);
if(v3.m!==1)err();v3=v3(v4);
v4=e.p[115];if(v4===null)err();
v5=O[21];
v6=e.p[7];if(v6===null)err();
v7=e.p[48];if(v7===null)err();
if(v6.m!==2)err();v5=v6(v7,v5);
v3=((f,g,h)=>(x,w)=>call(g,call(h,x,w),has(f)?call(f,x,w):f))(v5,v4,v3);
v4=e.p[115];if(v4===null)err();
v5=e.p[42];if(v5===null)err();
v3=((f,g,h)=>(x,w)=>call(g,call(h,x,w),has(f)?call(f,x,w):f))(v5,v4,v3);
if(v2.m!==2)err();v1=v2(v3,v1);
v0=call(v1,v0);
return v0;}

and 2◶"abcdef" ->

v0=e[1];if(v0===null)err();
v1=D[120](e);
v2=e[5];if(v2===null)err();
v3=e.p[115];if(v3===null)err();
v4=e[1];if(v4===null)err();
v5=e[4];if(v5===null)err();
v6=e[2];if(v6===null)err();
v4=call(v5,v4,v6);
v2=call(v3,v2,v4);
if(v1.m!==1)err();v1=v1(v2);
v2=e[2];if(v2===null)err();
v0=call(v1,v0,v2);
return v0;}

Am I missing a simple symbol for echoing / printing in these situations? I would love some clarity here.

Macron not explained in expressions tutorial

I apologize if this is not the place for this type of commentary. Feel free to redirect me as appropriate.

I noticed that the use of a macron for a minus sign goes unexplained in the Expressions tutorial (unless I missed it. I did a few searches). For people coming from APL this isn’t a problem but depending on the target audience perhaps it deserves some mention.

I hope you find this observation useful.

Regards

Should random primitives have APL/BQN-like symbols?

I am very new to APL/BQN and am very enamoured with your project, which, after many months of hunting down which programming language I was going to learn next, finally your pitch has seduced me 🛸. Very exciting.

I have one comment though. With the increasing growth of probabilistic programming languages and libraries, and with the huge importance of random number generation in machine learning, would it be worthwhile to extend the BQN symbol set with random number primimives, as opposed to the keywords currently proposed?

It seems to me that an even larger part of mathematical and statistical programming in the future will deal with randomness and this might help the concept of the notation as a tool of thought?

Am I right that Dyalog APL has ? as a symbol for "roll", for example? I don't seem to be able to find it in BQN.

Roadmap

Fantastic project, is there a roadmap for this, or milestones, or release tag as milestone?

Nice. Is there a Java JNI on CBQN plan?

I made @jackokring/majar as a simple language so far. It has no numerics yet. A nice embedding might be a fun project for me sometime.

It does have a nice error handling mechanism though.

Tutorial: 1-Modifier example

The example here would be easier to grasp with other numbers. 4^2 == 2^4 which doesn't immediately show the intent of the Swap, because the output is the same, with or without the Swap. Could you take 3 or 5 instead of 4?

Idea: BRFI?

In Short: What do You think about setting up something similar to scheme's SRFI system?

In Long: As I am (slowly) getting my feet under me with BQN and array programming in general, I was looking on ways to (eventually) contribute. On the community page, one of the things mentioned is the need for libraries to be written.

As a Lisper, I've greatly enjoyed the structure and reliability that SRFI libraries have added across implementations. Because the actual requests are abstracted away from code, they are both easier to understand and testably conformant to a standard. If I use SRFI-1 on Guile Scheme, it will work (nearly function for function) on Chez Scheme or Chicken.

Especially since BQN is so new, now might be a good time to allow for a system like this, where people might submit proposals for systems they would like to have in BQN according to a template, feedback from the community might be gathered, and then a standard for a specifically-named library, independent of implementation, might allow people to implement a consistent programming experience.

Yes, I could just set something like this up alone, but I both wanted to see what the reaction was here first and wanted it to be more than a personal project.

WDYT?

Allow Emojii variable names

image

Why can't I use the flying saucer Emojii, in the language for flying saucers!?

I want to be able to sprinkle my hieroglyphic BQN code, with emojii. ASCII begone! camelCase getouttahere.

This would be properly fun (even if discouraged 'officially').

Can it be done? You're using UTF-16 already, right? Most terminals, VIM, etc, support it no problem. According to this, they're encodable using UTF-16.

You know you want to! (or at least, I certainly do!)

Only slightly more seriously:
image

So at the very least, Unicode support for variable names?

Python doesn't support emojii variable names however, and...although I'm not sure this is good for the argument, but Javascript does. More interestingly, so does Swift:

image

Code in documentation for Assert may not show the correct outputs

In the section on assert with a left argument, the output doesn't look quite right. The codeblock

    "Message" ! 0
ERROR
    ⟨∘,"abc",˜⟩ ! '0'  # Okay this is not a very helpful printout
ERROR

doesn't produce the same output when you run it in the online REPL, which makes sense since it stops execution after the first failed assertion, but I think the output ERROR might not be right. Could we split the asserts into two code blocks, then change ERROR to the result in the online REPL or CBQN?

Emacs support outdated ?

Hi, just starting with BQN !

This is a small detail, but I think the documentation for bqn-mode is outdated, it seems that (require 'gnu-apl-mode) should be replaced with (require 'bqn-mode) (since it is was is provided by bqn-mode.el).

Emacs support

Any plans on adding emacs support? (I sadly don't program in elisp :/)

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.