Format for each entry:
Primary influences (★ in the catalog) get full entries. The rest are grouped, shorter, but every language in the catalog is covered.
Good
Bad
Lume takes
asm blocks with typed register binding, inside unsafe. Inline, not a separate file.@repr(c), @packed, @align(n), explicit field order. What you declare is what’s in memory.freestanding target: no runtime, no stdlib, write a kernel in Lume alone.Good
where). Still the fastest numeric code on Earth because the compiler knows arrays don’t alias.Bad
I–N are integers) — a famous source of bugs.COMMON blocks; GOTO spaghetti before FORTRAN 77.Lume takes
tensor[f32, 3, 224, 224].Good
Bad
Lume takes
comptime with the full language.Good
PIC 9(7)V99). Floating-point money is a bug; COBOL knew in 1959.Bad
ADD 1 TO X GIVING Y); 400+ reserved words.ALTER statement (self-modifying GOTO).Lume takes
decimal(p, s) as a built-in numeric type with exact arithmetic and declared precision. Money is never a float.@layout).Good
begin…end, recursion, call-by-name, BNF for the grammar. Defined how languages are described.Bad
Lume takes
grammar/lume.ebnf), and a specification that is normative.Good (Simula)
Good (Smalltalk)
ifTrue:, do:).Bad
final, interfaces, composition).Lume takes
dyn Trait) when asked.Good
PRINT 2+2, see 4. Millions learned on it. Zero ceremony to start.Bad
GOTO taught a generation unstructured code (Dijkstra’s famous complaint).Lume takes
lume with no arguments opens a REPL; a single .lume file with top-level statements runs as a script. Zero ceremony for beginners, same language for experts.Good
1..100, enumerations, sets set of Color, records with variants, nested procedures, with. Many of these have never been bettered.Bad
Lume takes
int in 0..150, checked at compile time when possible and at runtime (or at boundaries) otherwise. Enums, sets (set[Color], bit-set backed), variant records (as tagged unions = enum with payloads).Good
Bad
NULL, arrays decaying to pointers, the preprocessor (text macros, #include copying files), no modules, no namespaces, no generics (void* casts), integer promotion rules, errno.Lume takes
extern "C" both directions, generate headers, consume headers directly (import c "stdio.h" à la Zig).unsafe when it is actually unsafe.comptime replace every legitimate use of #define.Good
Bad
!) and side effects break the declarative model; the Byrd box debugging mental model is hard.Lume takes
query (see dBase and SQL below): fixpoint relations over tables, usable for program analysis, authorisation rules, inference. Declared, type-checked, compiled.Good
Bad
String, Text, ByteString…).let … in, ;;, 'a), weak tooling and library ecosystems for decades (OCaml fixed it late with opam/dune).Lume takes
enum with payloads, exhaustive match, Option/Result derived from them.lazy values, iterators are lazy by design).test property).Good
Bad
SELECT … FROM … WHERE) is backwards from the logical order (FROM → WHERE → SELECT); hard to compose; CTEs and subqueries bolted on.Lume takes
query expression in the core language, type-checked against the record type, in logical order (from/where/group/order/select), composable as a value, working over in-memory collections, files, and external databases through the same syntax (the LINQ insight, done at the language level and compiled to the backend’s native plan).T? optionals replace NULL; joins return explicit Option.Good
IMPORT, qualified names. Wirth defined the module system every later language adopted (Go’s packages descend from here).Bad
Lume takes
pub exports, no cyclic imports, module = file or directory, hierarchical names. Interfaces are what pub exposes; a lume doc extracts them.freestanding target and std.os traits are designed so that an OS can be written in Lume and user programs recompiled against it (see 05-vision.md).Good
USE customers opens a table; LIST FOR balance > 1000 queries it; REPLACE … WITH … updates it; INDEX ON creates an index. No ORM, no connection strings, no SQL strings. Data operations were statements in the language.{|x| x * 2} (closures in 1990!), user-defined functions, replaceable database drivers (RDDs), SET RELATION (declarative joins), BROWSE (a full data grid in one statement), screen @ SAY/GET forms.Bad
&cmd) with no safety, global memvars by default, PUBLIC/PRIVATE dynamic scoping — maintenance nightmares.RLOCK(), FLOCK()).@ 10,10 SAY) didn’t survive the GUI transition.Lume takes
record and table[T] as core types. A table is a typed, columnar-or-row collection with optional indexes, that can be in memory, on disk (a modern, concurrent, crash-safe native format — the DBF spirit without the DBF limits), or a view over an external database.query statements/expressions over tables (see SQL). index, relation (declarative joins), seek, scan as typed operations.|x| x * 2) — syntax honours Clipper.> use customers; > list where balance > 1000.report block type and a declarative UI/form description in the standard library (not the core language), so business apps are short again.¯o operator becomes comptime and hygienic macros: the power without the runtime injection.Good
Pre, Post, Type_Invariant since Ada 2012), tasks and protected objects (safe concurrency since 1983), packages with private parts, generics, representation clauses (exact bit layout), exceptions with a model for real-time.Bad
Lume takes
requires, ensures, invariant on functions and types; checked in debug/test, optionally proven by the lume prove tool (SMT-backed, SPARK/Dafny-style) for the subset that admits it.modular (wrapping) integer types as in Ada.sync types; tasks → structured concurrency.@layout, @bits.Good
Drop is RAII.constexpr runs at compile time; move semantics avoid copies.std:: algorithms + iterators + ranges: generic programming (Stepanov) is a real paradigm.Bad
Lume takes
Drop with deterministic destruction order and defer for ad-hoc cleanup.dyn escape hatch; comptime instead of template metaprogramming..clone()), no implicit conversions (except safe widening of numeric literals), operators overloadable only through named traits.Good
Bad
Lume takes
std.actor): isolated tasks with mailboxes, supervisors with restart strategies, links/monitors. Typed messages (what Gleam/Pony add).Good
Bad
$_), TIMTOWTDI led to unmaintainable codebases, Perl 6 took 15 years and split the community.set -euo pipefail needed just to be sane, non-portable between shells. The most dangerous “language” in production (think rm -rf $DIR/).Lume takes
re"(?<year>\d{4})" yields a record with .year).std.sh: run processes with structured pipes, typed stdout/stderr/exit, and a syntax for pipelines (run "ls" | lines | filter …). Lume scripts replace Bash scripts without the quoting hell (the Nushell/Oil insight).Good
pip/PyPI; the ecosystem for science and AI (NumPy, pandas, PyTorch, Jax).with context managers, docstrings, decorators — many small ergonomic wins.Bad
self everywhere, late binding closures in loops, significant whitespace copy-paste hazards.Lume takes
with → using), generators (as lazy iterators), decorators (as attributes @…).Good
Bad
nil in tables, global by default, ~=, no integer type until 5.3, small stdlib, no unicode strings, fragmented (5.1 vs 5.4 vs LuaJIT).Lume takes
Good
yield; everything is an expression; a beautifully consistent object model; metaprogramming that made Rails possible (DSLs that read like English).Bad
method_missing magic defeats tooling; dynamic typing (Sorbet/RBS bolted on late).Lume takes
if, match, blocks return values).lume expand).Good
Bad
public static void main(String[] args), getters/setters, factory-factory patterns); checked exceptions (everyone agrees they failed); null (Hoare’s “billion-dollar mistake” — Java made it a NullPointerException culture); type erasure in generics; primitives vs boxed types; slow startup and heavy memory for CLI tools; the Oracle licensing scare; XML-era configuration culture.Lume takes
.lumb) for the interpreted/JIT tier — Lume compiles to native or to bytecode for a small VM — with adaptive optimisation ideas from HotSpot available where they pay (plugins, scripts, REPL).null, no checked exceptions, no boxing: generics are reified and monomorphised.lume fmt/test/doc/bench/prof and a language server (LSP) shipped with the compiler.std.actor supervisors (see Erlang) and the “an agent is a program” model (see §2.5 of the vision), Lume targets multi-agent orchestration — many agents running, supervised and messaging each other concurrently — as a first-class use case, the thing JVM agent platforms (JADE/Akka) were built for, but with static types, no null, and compile-time data-race freedom.Good
async/await made asynchronous programming accessible; runs on every device; V8 proved dynamic languages can be fast via JIT; npm (for better or worse) is the largest ecosystem.tsc errors are good.Bad
== coercion, this binding, hoisting, var, undefined and null, prototype confusion, no integers, callback hell before promises, the npm supply-chain risks (left-pad, event-stream, etc.).any escape hatch; a build step for everything; the type system is Turing-complete and sometimes abused.Lume takes
async/await with structured concurrency underneath (not fire-and-forget promises).impl is nominal by default, shape types are structural — the TypeScript/Go interface insight for interop and duck-typing where it helps).net cannot open sockets — see Deno/Austral).xbase compatibility library and a translator for Clipper/Harbour code) to inherit that community.Good (Rust)
Option/Result + ?, iterators that compile to loops, unsafe as a clearly delimited contract, macros (declarative + procedural), Drop, slices, zero-cost abstractions.rustfmt, clippy, rustdoc, rust-analyzer; the best error messages ever written; editions for evolution.Bad
'a) leak into APIs; self-referential structs, async + lifetimes, Pin, trait objects with generics — complexity accretes.::, &mut, <'a, T: Trait + 'a>, .unwrap() everywhere in examples, Box<dyn Fn(&str) -> Result<(), E> + Send + 'static>.Send bounds). No default allocator abstraction in std (Zig does this better). Orphan rules limit trait impls.Lume takes
pub boundaries that return borrows, and even then usually elided.own to move in, mut to borrow mutably. The common case needs no sigils.rc[T]/arc[T]/cell[T] have short names and literal syntax; the compiler suggests them when the borrow checker fails, instead of a wall of text. A @gc region (optional tracing GC for a subgraph, like Nim’s ORC or D’s) exists for the parts of a program where ownership is the wrong model (compilers, GUIs, graph algorithms) — chosen per type/region, never global.?, Result/Option, exhaustive match, iterators, Drop, slices, unsafe contracts, editions, cargo-class tooling.-O0) and incremental compilation designed in, not retrofitted.fn sort[T: Ord](items: mut [T]) — square brackets, no angle-bracket ambiguity.Good
gofmt), fast compilation, a single static binary, cross-compilation by env var.select (CSP): concurrency accessible to every developer; the runtime multiplexes millions of goroutines.defer, composition over inheritance, excellent standard library (net/http, encoding), tooling (go test, go vet, pprof, race detector), the fastest GC pause story among GC’d languages.Bad
nil (pointers, maps, interfaces — a nil interface vs interface holding nil is a trap); if err != nil repeated 3 times per function; no sum types/enums; generics arrived 12 years late and are limited; zero values can hide bugs; interface{}/any casts; GC pauses and memory overhead make it unsuitable for kernels/real-time/embedded without effort; goroutine leaks (no structured concurrency); no immutability; GOPATH years; the lack of expressiveness pushes code generation (go generate).Lume takes
defer; structural shape types alongside nominal traits; a select over channels; one formatter; static binaries; cross-compilation built in; a race detector in the test runner (ownership makes most races compile errors already).scope blocks own their tasks (no leaks, cancellation propagates).? to remove the boilerplate, and typed error sets (Zig) so the compiler knows what can fail.Good
when compile-time branches; UFCS (a.f(b) ≡ f(a, b)), which makes APIs fluent without methods; multiple memory strategies (ARC/ORC/manual) chosen per program; effect tracking ({.raises: [].}, {.tags.}), distinct types, exceptions optional.Bad
fooBar == foo_bar) is contentious; small team → ecosystem gaps and compiler bugs; the proliferation of pragmas {.…}; too many ways to do memory; identity crisis (systems vs scripting); nimble tooling weaker than cargo.Lume takes
comptime, when branches, UFCS as the method-call rule (any function whose first parameter is T is callable as value.f()), distinct/newtype wrappers (type UserId = distinct int).pub.rc/arc + optional @gc region), not a per-program switch.Good
Bad
Lume takes
let is immutable; var mutable). Persistent collections (pvec, pmap) in the standard library with literal syntax; the ownership model makes in-place mutation of uniquely-owned values safe and fast, so Lume gets both the Clojure safety and the C performance (“mutable value semantics”, see Hylo).std.sync.Good
T?, ?., ?:, smart casts) on a mainstream platform; extension functions; data classes; coroutines with structured concurrency (coroutineScope) — the first mainstream structured-concurrency implementation; trailing lambdas → DSLs (Gradle KTS, Compose); interop with Java so good that adoption was frictionless; pragmatic (not academic) design; multiplatform (JVM/JS/native).Bad
Lume takes
?., ??), smart casts after a check, data records with auto-derived Eq/Hash/Show, extension functions (via UFCS), trailing closures, structured concurrency scopes.Good
guard, defer, result builders (declarative DSLs → SwiftUI), ownership features arriving (borrowing/consuming, ~Copyable), structured concurrency with actors (2021) — a thoughtful synthesis of Rust and Kotlin ideas for app developers.Bad
Lume takes
guard (early-exit with binding); result-builder-style declarative blocks for UI/config DSLs through macros.rc/arc as the shared tier with cycle detection at comptime where possible and a weak escape.Good
.), unicode operators, macros (Lisp-style on a normal syntax), metaprogramming, differentiable programming (Zygote), great REPL/notebooks.Bad
Lume takes
impl Add[Matrix, Vector]..+, .*) for arrays/tensors; unicode operators allowed (ASCII equivalents always exist).Good
Bad
Lume takes
lume publish computes the API diff and refuses an incorrect version bump.Good
comptime: ordinary Lume code executed at compile time replaces generics, macros and templates — types are values at comptime. Explicit allocators passed as parameters (no hidden heap). Error unions (!T) and error sets with try; defer/errdefer; no hidden control flow; C interop by importing headers directly, cross-compile to anything out of the box (Zig is also the best C/C++ cross-compiler); small, learnable; undefined must be explicit; build system in Zig itself.Bad
defer only); pre-1.0 churn; no package registry.Lume takes
comptime as a core feature; error unions (fn f() -> T ! E) with inferred error sets; defer/errdefer; explicit allocators as an option (the stdlib is allocator-aware; the default allocator is a global you can override, but kernels and embedded pass allocators explicitly); import c "header.h"; cross-compilation to every target from any host; undefined must be written.Good
owned/borrowed/inout), struct vs class tiers, parametric compile-time metaprogramming, SIMD types in the language, autotuning. The first mainstream attempt at a language designed for the AI hardware era.Bad
Lume takes
@autotune for kernel parameters.Good: made programmable money accessible; showed that a language can define an economic platform.
Bad: billions of dollars lost to reentrancy, integer overflow, visibility defaults, delegatecall, and a JS-like syntax that gave false confidence. Language design mistakes have a dollar value.
Lume takes: when the stakes are high, the language must make the wrong thing impossible (checked arithmetic by default, explicit visibility, no reentrant default, linear/resource types for assets — see Move).
.lumb, like O-code/p-code); and the PL/I warning tattooed on the spec: size budget.<-); MATLAB is proprietary and 1-based; NumPy’s shapes are runtime-only (shape errors at runtime are the #1 bug class in ML code).match over text streams; a readable but formal syntax (English words, strict grammar); no stringly typing.swap dup rot); no types; every program is a new language.freestanding + std.repl).^PATIENT(123,"name")), 60 years before Redis; the 4GLs delivered business applications with 5–10× less code than Java/C#; ABAP/PL/SQL run the world’s ERPs and databases.table, query, report, declarative forms — and persistence as a language feature (a typed, transactional, embedded store in std.data, accessed like variables: the MUMPS idea with types and ACID).requires/ensures/invariant, checked at runtime in debug), optionally proven by lume prove (SMT-backed, Dafny/SPARK-style) on the pure subset; refinement types as a lightweight dependent-type step (int where self > 0, [T; n] where n % 4 == 0); a path to export to Lean for hard proofs. The goal: a kernel or a neural-network runtime where the critical 5% is proven, the rest is tested, in one language.select, par) is the sanest concurrency model and lives on in Go; Linda’s tuple spaces are a beautiful coordination model; Oz’s dataflow variables (a variable that blocks until bound) unify futures and logic variables; Cilk’s work-stealing and spawn/sync are the basis of every modern parallel runtime; Chapel/X10 made distributed-memory parallelism (PGAS) readable; Pony’s reference capabilities (iso, val, ref, box, tag, trn) prove data-race freedom at compile time with actors; Lingua Franca makes concurrency deterministic (reactors with logical time); Verse’s transactional/choice semantics; Bend compiles ordinary recursive functional code to run on thousands of GPU cores via interaction nets.select, work-stealing task runtime, par for/par map for data parallelism (Cilk/Chapel), actors with typed mailboxes and reference-capability-like guarantees via ownership (arc, Send/Sync-style marker traits), a deterministic-time option (std.time.logical) for simulations and robotics, and GPU/accelerator kernels written in Lume itself (the Bend/Mojo/Futhark/Triton insight), with the compiler handling the data-parallel lowering through MLIR. (Dataflow futures promise[T] were considered here and superseded by structured scope/spawn + typed chan[T].)fn read_config() -> Config / {io, alloc}), inferred, used for: capability security (a function without net cannot touch the network), purity (pure functions are provable, memoisable, parallelisable, usable at comptime), async (no function colouring — async is an effect), and resumable handlers for generators/coroutines. Content-addressed modules in the package store (Unison/Nix: no “dependency hell”; two versions coexist). Platform/application split as the OS boundary model (Roc).? / todo typed holes the compiler reports with the expected type and lets you run around); live reload in the dev tier; a structured editor projection (lume agent project / lume fmt round-tripping the canonical AST and surface projection). (Spreadsheet-style reactive signal[T] was considered here and dropped from the core spec in favour of algebraic effect handlers and versioned tables.)query), properties, events, async/await (C# invented the syntax), records, pattern matching, spans, a real decimal type, excellent tooling; F# — units of measure in types (float<m/s>), type providers (types generated from external schemas at compile time), computation expressions, pipelines |>; Scala — unification of OO/FP, implicits/givens, Spark; D — compile-time function evaluation, ranges, contracts, scope guards, @safe subset; Dart — sound null safety migration at scale, hot reload for UI; Crystal — proves Ruby syntax + static types + global inference works; Hylo/Val’s mutable value semantics (safety without a borrow checker: no first-class references, projections instead); Vale’s generational references; Austral’s linear types + capability-based security + no hidden anything; Odin/Jai — explicit context/allocators, SOA layout, the “programmer joy” of game devs; Carbon/Cppfront/Circle — how to migrate off C++ (interop-first, borrow checking added to C++ syntax).query (C#); units of measure in types (f64[m/s]) and type providers (comptime can read a schema — SQL, JSON, Protobuf, a CSV header — and generate types) from F#; pipelines |>; CTFE (D/Zig comptime); @safe by default with unsafe islands; SOA/AOS layout control (@soa); the Hylo insight that most code never needs explicit references (Lume’s default: value semantics + borrowing inferred, references as a visible, rarer tool).lume.toml is actually lume syntax with effects forbidden: data literals + pure functions, like Starlark/Nix/CUE) for build files, package manifests, infrastructure and OS configuration. One language, one parser, one type checker, from the config file to the kernel. The build system is Lume (Zig’s insight).kernel fn for data-parallel code with the compiler doing the lowering; algorithm/schedule split (@schedule attributes and a schedule DSL for kernel functions); a synchronous/real-time subset (realtime effect: no allocation, bounded time, verified WCET where possible) for control systems and kernels’ interrupt paths; a Chisel-style hardware generation library as a long-term goal (std.hw).gradient(f) as a language operator, autodiff on the compiler’s IR rather than on a tensor library’s tape; Jax’s function transformations (grad, vmap, jit, pmap) as composable higher-order operators; PyTorch’s eager usability; Dex’s typed indices (shape errors become type errors); ONNX as a model interchange format; the 2023–2025 “prompt languages” (DSPy, BAML, LMQL, SGLang) treat an LLM call as a typed function with a schema, optimise prompts like compilers optimise code, and compile structured output; neuromorphic languages (Nengo, Lava) program spiking networks with time as a dimension.05-vision.md): tensors with typed shapes and typed indices (Dex); autodiff as a language transformation on Lume’s own IR (grad f, jvp, vjp, vmap as first-class operators on any pure function, including control flow, like Enzyme/Zygote); kernel functions for accelerators; model as a type (a parametrised differentiable function with a serialisable state, ONNX export/import built in); probabilistic primitives (sample, observe, infer) in a prob effect, so a generative model is ordinary code; rules (rule … when … then …) compiled to a Rete/Datalog engine over tables; and LLM calls as typed functions (extern llm fn summarise(text: str) -> Summary with the schema enforced by constrained decoding, retries and evals in the language’s test runner) — the DSPy/BAML idea as a core feature, so an AI agent, its tools, its memory (tables) and its evaluation are one typed program.unsafe and the language has no notion of “privilege level”, “interrupt context” or “page table” — those live in conventions.freestanding target; realtime and interrupt effects (the type system knows this function may run in interrupt context and forbids allocation/blocking); capability types for kernel resources (a page, a port, a device register is a linear capability value — Austral/Move/seL4 style — that cannot be duplicated or forged); typed memory-mapped registers (@mmio); the platform/application split (Roc) as the kernel/userland boundary: userland code is parametrised by the capabilities the kernel passes it; software-isolated processes become possible because the compiler verifies memory safety (Singularity’s bet, without the GC); a reference OS (lume-os) as the project’s long-term proof.lume-core: a small typed IR with a formal semantics, ~30 constructs) that the full language desugars into. Everything fancy is sugar over a core small enough to prove things about and re-implement in a weekend — the key to self-hosting, to the verifier, and to porting Lume to a new machine.What each pillar of Lume owes to whom, in one table:
| Lume feature | Primary source | Secondary sources |
|---|---|---|
| Indentation syntax, readability | Python | Pascal, Nim, COBOL (readability), Ruby |
| Ownership + borrowing, no GC | Rust | Cyclone, Clean (uniqueness), Hylo (value semantics), Pony |
rc/arc shared tier, optional @gc region |
Swift (ARC), Nim (ORC) | Koka (Perceus), D |
Error unions ! E, ?, defer/errdefer |
Zig, Rust | Go (explicit errors), Swift |
T? optionals, ?., ?? |
Kotlin, Swift | ML (Option), Haskell (Maybe) |
ADTs + exhaustive match |
ML, Rust | Haskell, Prolog (patterns), Scala |
| Traits with associated types/defaults | Rust, Haskell | Swift protocols, Go (structural), Julia (multiple dispatch) |
Structured concurrency, scope, channels, select |
Kotlin, Go | Trio, Swift, Occam/CSP, Erlang |
| Actors + supervisors | Erlang/Elixir | Pony, Akka, Orleans |
comptime |
Zig | D (CTFE), Nim, C++ constexpr, Jai |
| Hygienic AST macros | Nim, Rust | Lisp/Scheme, Julia, Elixir |
record, table, query, index, relation |
dBase/Clipper/FoxPro, SQL | C# LINQ, MUMPS (persistent globals), 4GLs, Datalog |
decimal(p,s) |
COBOL | C#, dBase, PL/SQL |
| Range/refinement types, sets, enums | Pascal, Ada | Idris/Dafny (refinements), F# units |
| Contracts + gradual proof | Eiffel, Ada/SPARK, Dafny | Lean, F*, Whiley |
| Effect system | Koka, Effekt | Nim (effects), Haskell (monads, as the thing to avoid), Roc (platforms) |
Tensor shapes in types, autodiff, kernel, model |
Dex, Jax, Swift for TensorFlow, Mojo | Futhark, Halide, Triton, Julia/Zygote, Enzyme, FORTRAN (arrays) |
| LLM calls as typed functions, rules | DSPy/BAML/LMQL, OPS5/CLIPS | Prolog, Drools |
| Probabilistic primitives | Church/Gen/Stan/Pyro | |
Capability types, freestanding, interrupt/realtime effects |
seL4, Austral, Move, Rust kernels | Oberon, Singularity, Lustre, Ada |
| C interop by importing headers, cross-compile everywhere | Zig | Rust (bindgen), Nim |
Unified tooling (lume build/fmt/test/doc/pkg/repl/prove) |
Cargo/Rust, Go | Elm (semver enforcement), Nix/Unison (content-addressed store), Deno (permissions) |
| Config = restricted Lume | Zig (build.zig), Nix, Starlark, CUE | |
| Fast debug compilation, REPL, live reload | Turbo Pascal, Lisp, Smalltalk | Go, Dart, Erlang |
| Error messages as a product | Elm, Rust | |
| Typed holes, liveness | Hazel, Smalltalk | Idris, spreadsheets |
| Tiny verified core | Scheme, Brainfuck (minimalism), Oberon | Lean, seL4 |
| Size budget, remove features | Go, Oberon | PL/I and C++ as warnings |
Next: 02-principles.md turns this scoreboard into rules the design must obey, and 05-vision.md
is the out-of-the-box part — what a language for the AI era that can build an operating system
and a neural system should look like.