Code Monkey home page Code Monkey logo

curlies's Introduction

DISCLAIMER

This library is an experiment, and comes with heavier compilation times, a basic benchmark is provided at the end of this file.

I recommend NOT to use it in a production environment.

Curlies

A macro for object construction using {} (curlies).

With curlies, initialization of required fields is checked at compile-time. For object fields with a default value (available since nim 2.0), initialization is obviously not mandatory.

It's simply a macro equivalent for the common proc init[T](_: type T, ...) that uses the type's declaration to dispatch and check all required fields are provided. The output of a curlies construction is an object construction expression, no temporary variables are introduced.

But why?

I wanted to get a better grasp of nim's macro system and see how far it could be pushed to enable static checks on missing fields for object initialization.

Installation

Install curlies with nimble:

$ nimble install curlies

Alternatively, curlies can be installed with atlas:

$ atlas use curlies

Syntax

Curlies is defined as a typed macro:

macro `{}`*(T: typedesc, params: varargs[untyped]): untyped

It's somehow similar to rust's struct initialization syntax, the main difference being you cannot use a whitespace between the type and opening bracket {.

Borrowed features include:

type
  MyType = object
    myField: int
let
  myField = 1
  full = MyType{ myField: myField }
  short = MyType{ myField }
assert full == short
type
  MyType = object
    a, b, c: int
let
  original = MyType(a: 1, b: 2, c: 3)
  derived = MyType{ a: 4, ..original }
assert derived == MyType(a: 4, b: 2, c: 3)

Supported

Most nim types should work out of the box, tests currently cover:

Curlies behaviour differs based on the module where it is used.

  • for types declared in the same module, all non-default fields are enforced.
  • for types declared in another module, only exported fields are enforced, unless of course they bring a default value.

Usage

Equivalent to regular object construction:

type
  Person = object
    name: string
    age, height: int
    favouriteNumber: int = 3

const
  alice = Person{
    name: "Alice",
    age: 30,
    height: 175
  }

echo alice
# (name: "Alice", age: 30, height: 175, favouriteNumber: 3)

Field init shorthand + update syntax

type
  Person = object
    name: string
    age, height: int
    favouriteNumber: int = 3

let
  name = "Bob"
  height = 155
  bob = Person{
    name,
    height,
    ..alice,
  }
echo bob
# (name: "Bob", age: 30, height: 155, favouriteNumber: 3)

Compilation error on missing fields

type
  Person = object
    name: string
    age, height: int
    favouriteNumber: int = 3

echo Person{ name: "Incomplete" }
# Error: @[age, height]: initialization required.

Compilation times

I compared compiling tests/tbasic.nim with its equivalent that uses regular object construction tests/tbasic_nocurlies.nim, numbers below:

  • With latest stable
$ nim -v
Nim Compiler Version 2.0.2 [Linux: amd64]
Compiled at 2023-12-15
Copyright (c) 2006-2023 by Andreas Rumpf

git hash: c4c44d10df8a14204a75c34e499def200589cb7c
active boot switches: -d:release

$ hyperfine \
    'nim c -f --hints:off -o:/tmp/tbasic tests/tbasic.nim' \
    'nim c -f --hints:off -o:/tmp/tbasic tests/tbasic_nocurlies.nim'
Benchmark 1: nim c -f --hints:off -o:/tmp/tbasic tests/tbasic.nim
  Time (mean ± σ):      1.707 s ±  0.051 s    [User: 3.175 s, System: 0.706 s]
  Range (min … max):    1.652 s …  1.799 s    10 runs

Benchmark 2: nim c -f --hints:off -o:/tmp/tbasic tests/tbasic_nocurlies.nim
  Time (mean ± σ):      1.557 s ±  0.031 s    [User: 3.003 s, System: 0.699 s]
  Range (min … max):    1.505 s …  1.587 s    10 runs

Summary
  nim c -f --hints:off -o:/tmp/tbasic tests/tbasic_nocurlies.nim ran
    1.10 ± 0.04 times faster than nim c -f --hints:off -o:/tmp/tbasic tests/tbasic.nim
  • With latest devel
$ nim -v
Nim Compiler Version 2.1.1 [Linux: amd64]
Compiled at 2024-01-14
Copyright (c) 2006-2024 by Andreas Rumpf

git hash: ab4278d2179639f19967431a7aa1be858046f7a7
active boot switches: -d:release

$ hyperfine \
    'nim c -f --hints:off -o:/tmp/tbasic tests/tbasic.nim' \
    'nim c -f --hints:off -o:/tmp/tbasic tests/tbasic_nocurlies.nim'
Benchmark 1: nim c -f --hints:off -o:/tmp/tbasic tests/tbasic.nim
  Time (mean ± σ):      2.805 s ±  0.271 s    [User: 5.384 s, System: 2.553 s]
  Range (min … max):    2.447 s …  3.368 s    10 runs

Benchmark 2: nim c -f --hints:off -o:/tmp/tbasic tests/tbasic_nocurlies.nim
  Time (mean ± σ):      2.252 s ±  0.230 s    [User: 4.615 s, System: 1.920 s]
  Range (min … max):    2.061 s …  2.741 s    10 runs

Summary
  nim c -f --hints:off -o:/tmp/tbasic tests/tbasic_nocurlies.nim ran
    1.25 ± 0.18 times faster than nim c -f --hints:off -o:/tmp/tbasic tests/tbasic.nim

On my computer, curlies comes with 10 to 25% slower compilation, depending on the compiler version.

Well this is an experiment anyway, I must advise against using it in a production environment.

curlies's People

Contributors

svenrdz avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

jopraveen

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.