{"id":13610582,"url":"https://github.com/munificent/lark","last_synced_at":"2026-01-10T05:08:44.608Z","repository":{"id":989721,"uuid":"796875","full_name":"munificent/lark","owner":"munificent","description":"The Lark programming language.","archived":true,"fork":false,"pushed_at":"2010-07-25T18:15:55.000Z","size":656,"stargazers_count":59,"open_issues_count":0,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-07T16:44:11.002Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/munificent.png","metadata":{"files":{"readme":"README","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2010-07-25T18:14:36.000Z","updated_at":"2024-09-12T11:19:03.000Z","dependencies_parsed_at":"2022-08-16T11:45:16.453Z","dependency_job_id":null,"html_url":"https://github.com/munificent/lark","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/munificent%2Flark","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/munificent%2Flark/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/munificent%2Flark/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/munificent%2Flark/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/munificent","download_url":"https://codeload.github.com/munificent/lark/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248642308,"owners_count":21138350,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T19:01:46.080Z","updated_at":"2025-04-12T22:34:16.499Z","avatar_url":"https://github.com/munificent.png","language":"Java","readme":"\n    Lark\n    ----\n\nLark is an experiment in designing a homoiconic language with a syntax\ninspired by SmallTalk. It's very early, so there isn't much to see\nyet, but you can play with it.\n\n\nLark Syntax\n===========\n\nCore syntax\n-----------\nInternally, Lark has a very simple syntax. It's more complex than\nScheme, but just barely. It has three core expression types:\n\n- Atoms are things like names, numbers and other literals.\n- Lists are an ordered set of other expressions.\n- Calls are a pair of expressions, the function and the argument.\n\nThat's it. Scheme has the first two, and Lark just adds one more.\nEvery expression in Lark can be desugared to these core elements. The\nrest of this section explains the syntactic sugar added on top of\nthat, but that's handled only by the parser. To the interpreter, the\nabove is the only syntax.\n\nThis *should* mean that it'll be as easy to make powerful macros in\nLark as it is in Scheme.\n\n\nNames\n-----\nThe simplest syntactical element in Lark are names, identifiers. There\nare three kinds of identifiers. Regular ones start with a letter and\ndon't contain any colons. Like:\n\n    a, abs, do-something, what?!, abc123\n\nThey are used for regular prefix function calls and don't trigger any\nspecial parsing, so you can just stick them anywhere.\n\nOperators start with a punctuation character, like:\n\n    +, -, !can-have-letters-too!, !@#%#$$\u0026$\n\nAn operator name will cause the parser to parse an infix expression.\nIf you don't want that, and just want to use the name of an operator\nfor something (for example, to pass it to a function), you can do so\nby surrounding it in (). This:\n\n    (+) (1, 2)\n    \nis the same as:\n\n    1 + 2\n\nKeywords start with a letter and contain at least one colon. A colon\nby itself is also a keyword. Ex:\n\n    if:, :, multiple:colons:in:one:\n\nLike operators, keywords will trigger special parsing, so must be put\nin parentheses if you just want to treat it like a name.\n\nPrefix functions\n----------------\nThe basic Lark syntax looks much like C. A regular name followed by an\nexpression will call that named function and pass it the given\nargument. Ex:\n\n    square 123\n\nDotted functions\n----------------\nLark also allows functions to be called using the dot operator. It's\nfunctionally equivalent to a regular function call, but has two minor\ndifferences: the function and argument are swapped, and the precedence\nis higher. For example:\n\n    a.b c.d\n\nis desugared to:\n\n    (b(a))(d(c))\n\nSwapping the argument and function may sound a bit arbitrary, but it\nallows you to write in an \"object.method\" style familiar to many OOP\nprogrammers. For example, instead of:\n\n    length list\n\nyou can use:\n\n    list.length\n\nOperators\n---------\nOperators are parsed like SmallTalk. All operators have the same\nprecedence (no Dear Aunt Sally), and are parsed from left to right.\nThe expression:\n\n    a + b * c @#%! d\n    \nis equivalent to:\n\n    @#%!(*(+(a, b), c), d)\n\nKeywords\n--------\nLark has keywords that work similar to SmallTalk. The parser will\ntranslate a series of keywords separated by arguments into a single\nkeyword name followed by the list of arguments. This:\n\n    if: a then: b else: c\n\nis parsed as:\n\n    if:then:else:(a, b, c)\n\nLists\n-----\nA list can be created by separating expressions with commas, like so:\n\n    1, 2, 3\n\nParentheses are not necessary, but are often useful since commas have\nlow precedence. For example:\n\n    this:              means:\n\n    difference 1, 2     ===\u003e  (difference(1), 2)\n    difference (1, 2)   ===\u003e  difference(1, 2)\n\nBraces\n------\nA series of expressions separated by semicolons and surrounded by\ncurly braces is syntactical sugar for a \"do\" function call. This gives\nus a simple syntax for expressing a sequence of things that executed\nin order (which is what the \"do\" special form is for). So this:\n\n    { print 1, 2; print 3, 4 }\n    \nis parsed as:\n\n    do (print (1, 2), print (3, 4))\n\nNote that the semicolons are *separators*, not *terminators*. The last\nexpression does not have one after it.\n\nPrecedence\n----------\nThe precedence rules follow SmallTalk. From highest to lowest, it is\nprefix functions, operators, keywords, then \",\". So, the following:\n\n    if: a \u003c b then: c, d\n\nis parsed as:\n\n    (if:then:(\u003c(a, b), c), d)\n\nThat's the basic syntax. The Lark parser reads that and immediately\ntranslates it to the much simpler core syntax.\n\n\nRunning Lark\n============\n\nLark is a Java application stored in a single jar, you can run it by\ndoing either:\n\n  $ java -jar lark.jar\n\nOr, if you have bash installed, just:\n\n  $ ./lark\n\nThis starts up the Lark REPL, like this:\n\n  lark v0.0.0\n  -----------\n  Type 'q' and press Enter to quit.\n  \u003e \n\nFrom there you can enter expressions, which the interpreter will\nevaluate and print the result.\n\nYou can also tell lark to load and interpret a script stored in a\nseparate file by passing in the path to the file to lark:\n\n  $./lark path/to/my/file.lark\n\nBuilt-in functions\n==================\n\nSo what can you actually do with it? Not much, yet. Only a few\nbuilt-in functions are implemented:\n\n' \u003cexpr\u003e\n\n    The quote function simply returns its argument in unevaluated\n    form. Ex:\n    \n    \u003e ` print 123\n    : print 123\n    (note: does not call print function)\n\ndo \u003cexpr\u003e\n\n    If the expression is anything but a list, it simply evaluates it\n    and returns. If it's a list, it evaluates each item in the list,\n    in order, and then returns the evaluated value of the last item.\n    \n    In other words, it's Lark's version of a { } block in C. Ex:\n    \n    \u003e do (print 1, print 2, print 3)\n    1\n    2\n    3\n    : ()\n\nprint \u003cexpr\u003e\n\n    Simply evaluates the argument and prints it to the console.\n\n\u003cparams\u003e =\u003e \u003cbody\u003e\n\n    Creates an anonymous function (a lambda). \u003cparams\u003e should either\n    be a single name or a list of parameter names. \u003cbody\u003e is an\n    expression that forms the body of the function. Ex:\n    \n    \u003e (a =\u003e do (print a, print a)) 123\n    123\n    123\n    : ()\n\ndef: \u003cname\u003e is: \u003cexpr\u003e\n\n    Binds a value to a variable in the current scope. \u003cname\u003e should\n    be a single name. \u003cexpr\u003e will be evaluated and the result bound\n    to the name. Ex:\n    \n    \u003e def: a is: 123\n    : ()\n    \u003e a\n    : 123\n\nif: \u003ccondition\u003e then: \u003cexpr\u003e\nif: \u003ccondition\u003e then: \u003cexpr\u003e else: \u003celse\u003e\n\n    Evaluates the condition. If it evaluates to true, then it\n    evaluates and returns \u003cexpr\u003e. If it evaluates to false, it will\n    either return () or, if an else: clause is given, evaluate and\n    return that. Ex:\n    \n    \u003e if: true then: print 1 else: print 2\n    2\n    : ()\n\nbool? \u003cexpr\u003e\nint? \u003cexpr\u003e\nlist? \u003cexpr\u003e\nname? \u003cexpr\u003e\nunit? \u003cexpr\u003e\n\n    Evaluates \u003cexpr\u003e then returns true if it is the given type. Note\n    that ().list? returns *true* because unit is the empty list. Ex:\n    \n    \u003e 123.int?\n    : true\n    \u003e ('foo).name?\n    : true\n    \u003e 123.list?\n    : false\n\n\u003cint\u003e \u003cexpr\u003e\n\n    Evaluates \u003cexpr\u003e, expecting it to be a list. Returns the item\n    at the \u003cint\u003e position in the list (zero-based). Basically, this\n    means an int is a function you can pass a list to to get an item\n    from it. Ex:\n    \n    \u003e 0 (1, 2, 3)\n    : 1\n    \u003e (4, 5, 6, 7).3\n    : 7\n    \ncount \u003cexpr\u003e\n\n    Evaluates \u003cexpr\u003e, expecting it to be a list. Returns the number of\n    items in the list. Ex:\n    \n    \u003e (1, 2, 3).count\n    : 3\n\nThat's it so far. Like I said, very early...","funding_links":[],"categories":["Uncategorized"],"sub_categories":["Uncategorized"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmunificent%2Flark","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmunificent%2Flark","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmunificent%2Flark/lists"}