Giter Site home page Giter Site logo

trizen / sidef Goto Github PK

View Code? Open in Web Editor NEW
113.0 8.0 2.0 10.71 MB

A modern object-oriented programming language implemented in Perl.

Home Page: https://tio.run/#sidef

License: Artistic License 2.0

Perl 59.14% Ruby 40.41% CSS 0.01% JavaScript 0.01% Shell 0.14% Julia 0.12% Lua 0.06% Raku 0.11%
perl programming-language sidef object-oriented transpiler

sidef's Introduction

The Sidef Programming Language

Sidef is a modern, high-level programming language designed for versatile general-purpose applications, drawing inspiration from the principles of Ruby, Raku, and Julia.

            **   **         ****   *           *********   *********
          * * ** * *        ****   **          ** ** **    ** ** **
           **   **          ****   ***         *********   *  *  *
  **        **        **    ****   *  *        ******      ******
* * *     * * *     * * *   ****   ** **       ** **       ** **
 **        **        **     ****   ******      ******      *  *
       **   **              ****   *  *  *     *********   ***
     * * ** * *             ****   ** ** **    ** ** **    **
      **   **               ****   *********   *********   *
  • Key features of Sidef include:

    • Object-oriented programming
    • Functional programming
    • Functional pattern matching
    • Optional lazy evaluation
    • Multiple dispatch
    • Lexical scoping
    • Lexical closures
    • Keyword arguments
    • Regular expressions
    • Seamless integration with Perl modules
    • Optional dynamic type checking
    • Robust support for big integers, rationals, floats, and complex numbers

Resources

Questions & Answers

For assistance or inquiries regarding Sidef, please visit the dedicated discussion forum.

EXAMPLES

var y = ->(f) {->(g) {g(g)}(->(g) { f(->(*args) {g(g)(args...)})})}

var fac = ->(f) { ->(n) { n < 2 ? 1 : (n * f(n-1)) } }
say 10.of { |i| y(fac)(i) }     #=> [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]

var fib = ->(f) { ->(n) { n < 2 ? n : (f(n-2) + f(n-1)) } }
say 10.of { |i| y(fib)(i) }     #=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

ASCII generation of the Sierpinski triangle:

func sierpinski_triangle(n) {
    var triangle = ['*']
    { |i|
        var sp = (' ' * 2**i)
        triangle = (triangle.map {|x| sp + x + sp} +
                    triangle.map {|x| x + ' ' + x})
    } * n
    triangle.join("\n")
}

say sierpinski_triangle(4)

Output:

               *
              * *
             *   *
            * * * *
           *       *
          * *     * *
         *   *   *   *
        * * * * * * * *
       *               *
      * *             * *
     *   *           *   *
    * * * *         * * * *
   *       *       *       *
  * *     * *     * *     * *
 *   *   *   *   *   *   *   *
* * * * * * * * * * * * * * * *

ASCII generation of the Mandelbrot set:

func mandelbrot(z, r=20) {
    var c = z
    r.times {
        z = (z*z + c)
        return true if (z.abs > 2)
    }
    return false
}

for y in (1 `downto` -1 `by` 0.05) {
    for x in (-2 `upto` 0.5 `by` 0.0315) {
        print(mandelbrot(Complex(x, y)) ? ' ' : '#')
    }
    print "\n"
}

Output:


                                                            #
                                                        #  ###  #
                                                        ########
                                                       #########
                                                         ######
                                             ##    ## ############  #
                                              ### ###################      #
                                              #############################
                                              ############################
                                          ################################
                                           ################################
                                         #################################### #
                          #     #        ###################################
                          ###########    ###################################
                           ###########   #####################################
                         ############## ####################################
                        ####################################################
                     ######################################################
#########################################################################
                     ######################################################
                        ####################################################
                         ############## ####################################
                           ###########   #####################################
                          ###########    ###################################
                          #     #        ###################################
                                         #################################### #
                                           ################################
                                          ################################
                                              ############################
                                              #############################
                                              ### ###################      #
                                             ##    ## ############  #
                                                         ######
                                                       #########
                                                        ########
                                                        #  ###  #
                                                            #

Additional Examples

INTERACTIVE MODE

sidef

TRY IT ONLINE

AVAILABILITY

LICENSE AND COPYRIGHT

  • Copyright (C) 2013-2024 Daniel Șuteu, Ioana Fălcușan

This program is free software; you can redistribute it and/or modify it under the terms of the Artistic License (2.0). You may obtain a copy of the full license at:

https://www.perlfoundation.org/artistic-license-20.html

Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license.

If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license.

This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder.

This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed.

Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

sidef's People

Contributors

catb0t avatar ioanaf avatar marwal-88 avatar tcheukueppo avatar trizen 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

sidef's Issues

Make the Bool class interchangeable with Number

>> class Bool { 
    method +(arg) { self.to_int + arg } 
    method -(arg) { self.to_int - arg } 
    method *(arg) { self.to_int * arg } 
    method /(arg) { self.to_int / arg } 
}
=> Sidef::Types::Bool::Bool
>> false + 1
=> 1
>> true + 1
=> 2
>> true * 3
=> 3
>> true / 2
=> 0.5

But:

>> class Bool { 
    method +(arg) { self.to_int + arg } method -(arg) { self.to_int - arg } 
    method *(arg) { self.to_int * arg } method /(arg) { self.to_int / arg } }
=> Sidef::Types::Bool::Bool
>> class Number { 
    method add(Bool arg) { self + arg.to_int } 
    method sub(Bool arg) { self - arg.to_int } 
    method mul(Bool arg) { self * arg.to_int } 
    method div(Bool arg) { self / arg.to_int } }   
=> Sidef::Types::Number::Number
>> false + 1
=> 1
>> false + 1 + false * true / 4 / false * true
[ERROR] Invalid argument `false` of type Bool in Number.add(). Expected an argument of type Number!
=> nil
>> false + 1
=> 1
>> false + true
[ERROR] Invalid argument `true` of type Bool in Number.add(). Expected an argument of type Number!
=> nil
>> class Number { method add(Bool arg, Bool arg2) { arg.to_int + arg2.to_int } }
=> Sidef::Types::Number::Number
>> false + true
[ERROR] Invalid argument `true` of type Bool in Number.add(). Expected an argument of type Number!
=> nil

(Same goes if I define Number.+(), etc.) I'm not sure what's wrong, but it'd be sweet if Sidef treated true and false numerically interchangeable and usable with number operators by default, like in Python and Perl 6.

Add a way to change the step of a given Range object

Add the Range object method by for setting the step. Also, add more methods like start (which returns the first value of the range) and the end method (which returns the last value of the range).

0...10 by(2).each { |n| say n };

override built-in classes

Would be good if you could do:

my $interpreter = Sidef->new(
   classes => {
      Sys   => 'My::Sidef::Sys::Sys',
   },
);

And that instance of Sidef would use My::Sidef::Sys::Sys instead of Sidef::Sys::Sys. This would allow you to run scripts in a safe evaluation context which didn't have access to Sys.exec() and so on.

Inner classes get their parent's variables but none of the methods

#! sidef -WkP12

class ArgParse () {

  class Option (long) {}

  has Hash prog_args = Hash()
  has Hash prog_info = Hash()

  method option (long_name) {
    var a = Option(1)
    a.option # -> Undefined method
    self.prog_args.append(long_name, Option(long_name))
    self.prog_args
  }

}

say ArgParse().option("f")

the output (in 3.50) is

Hash("f" => Option(long: "f", prog_args: Hash(), prog_info: Hash()))

The Option value in the hash has members prog_args and prog_info which are not defined in Option, but in its outer class. Option's version of the members do not have the same values as ArgParse's version, which implies they're not pointers but they are just copied members.

This would make sense to me if Option also inherited the methods from its outer "super"class, but it doesn't seem to.

Is this intentional, or a bug? Is it to discourage me from using nested classes except to subclass data?

Sequence Typenames can't be ~~ smart-matched

Sorry if this is nitpicky, but some builtin Type typenames (the iterable ones) can't be smart-matched against directly because they throw the error

Pair ~~ Pair # -> true
Pair().class ~~ Pair.class # -> true 
Pair.class ~~ "a" # -> false 

Pair ~~ "a" # error
"a" ~~ Pair # error 
1 ~~ Pair  # error 
Can't use string ("Sidef::Types::Array::Pair") as an ARRAY ref while "strict refs" in use at /home/cat/perl5/lib/perl5/Sidef/Types/Array/Array.pm line 2358.

Array, Pair, Matrix, Bag, Hash, Regex and Set all do this; Null does not, which implies that it's not a missing method but just a weird regression. Array.pm line 2358 is Array.contains and the error line for Hash / Set is 500, inside Hash.exists.

It works fine if you call a method on the typename or have an object of that type, like Array.class or 1~~[1, 2] == true.

I know I should use the .class or .ref method to test the type, but I think the error message is wrong or confusing, those expressions should just be false.

Add the String.inspect() method

Add the String.inspect() method (with Data::Dump) to return a double-quoted string (without base64 encoding).

"\t © \0 \n".inspect();    # returns: "\t \xA9 \0 \n"

Transform hash pairs into key/value

Add support to transform Pair objects into key/value hash elements.

var pair = "hello":"world";   # creates a new Pair object
var hash = Hash.new(pair);    # creates a new Hash: ("hello" => "world")
say hash[:hello];             # fetches the value of "hello" and prints "world"

This feature also makes the creation of hashes much easier:

var hash = Hash.new(
  cat: "feline",
  dog: "canine",
);

Support for subsets

Implement support for subsets with the subset keyword, which can inherit types (preferably, multiple types, creating an union type) and takes an optional block for validating the argument even further.

subset PointLimit < Number { |n| (n >= -10) && (n <= 10) }

class Point(PointLimit x, PointLimit y) {
    method to_s { "(#{x}, #{y})" }
}

say Point(-5, 6)                   # should print "(-5, 6)"
say Point(-50, 60)                 # the validation must fail here

Valid declarations should be:

subset Name
subset Name { ... }
subset Name < T1, T2
subset Name < T1, T2 { ... }

`this`-like object inside classes

Sidef's lack of a this-like object makes class code look very clean but I find it difficult to tell whether a name is global, a class member or a local variable / method parameter, when reading longer methods.

Also, it would be nice to be able to access a global or method var named x at the same time as a class member named x (referred to like this->x)

The exact C++-style of this-> doesn't make much sense for Sidef though, I'm not sure what syntax would? Perhaps $.x or $this.x or ::x or ➔x or something?

Or if you don't want this, is it possible to extend Sidef within Sidef to add an auto-variable to classes, without having to change the interpreter?

Assignment lifetimes / cloning

I think Sidef doesn't really abuse Perl references for new objects, compare with CPython where you have to tread carefully to keep your object references and identity comparisons bug-free.

But it does abstract over Perl in the object management area?

Or does it map directly to Perl, where the answer is, "it does whatever Perl would do"?

var i = very_large_immediate_iterable # Array, nested Pairs, String, Matrix, Bag (not a RangeNum)
i2 = i     # clone, or take reference and copy on write? 

var h = very_large_hash 
h2 = h     # similar 

var c = BigClass()
c2 = c  # do i have a reference to the object, or a separate copy

f(i, h, c)  # which objects are copied into the next scope and which are a pointer?

There are probably other examples I can't think of.

Access stack values from a variable

Idea:

   variable.get_stack();      # return the stack as an array
   variable.read_stack(0);    # return a value from the top of the stack

Implemented as:

   variable._stack_vals();   # returns the stack as an array
                             # returns nil if the variable doesn't have a stack

ARGF - argv stdin files (ARGV fh)

Add the ARGF special keyword as the filehandle which refers to the files specified as arguments or to the standard input when no argument is provided.

ARGF.each { |line|
    print line;
}

Errors in extremely long lines get cut but still show the caret

If you put a line like

(:«2 A 4 H 1 J 3 ...)[1..4].map{static(ß)=+<tsu rehton fedirekca>,.+(ß<<1.pop.reverse+(.len ?32.chr :%\,\))}.'join'say

into a file or the interpreter the error is

sidef: Who are you!?

File : -i
Line : 1
Error: expected a method

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(:«2 A 4 H 1 J 3 S»...)[1..4].map{static(ß)=+<tsu rehton fedirekca>,.+(ß<<1.pop.
                                                                                         ^

the caret is pointing to whitespace because the line was cut to the format; moreover the location of the error is not actually shown

the options to fix it are

  1. just add the character position / column number of the error to the Line : line:col part (easy)
  2. only show N characters around the erroring part of the line, instead of showing the entire line
  3. the line should be an exception to the format's max length, and stick out
  4. the entire format's max length should extend to the line length, if it's longer
  5. the line should be wrapped onto the next output line, iff the error is at a position that isn't within the format's max length (so that in the first case, the caret is shown directly below the first line and not in conflict with the wrapped line)

Where to add documentation?

The long intro for the question is:

The GitBooks book is a really good reference for simple language stuff, but leaves out many of the finer details that are covered in the wiki. It's also not editable by anyone else, and I don't think you can make a Sidef organisation for it since https://trizen.gitbooks.io is on "Legacy Gitbooks".

I made a new Sidef organisation in Gitbook.com, you can join as an administrator and maybe there is some way to export https://trizen.gitbooks.io/sidef-lang into the new "Spaces" format.

The GitHub wiki has (almost) all the reference on the home page, which I think would make more sense broken into individual pages, but this way you can Ctrl+F and search the entire doc (otherwise you can only search page titles).

GitHub wikis are more convenient but don't have full-text search, meanwhile GitBook is a lot more complicated and not editable by just any user.

What's new in V2 Gitbook

So should I edit (or re-organise) the GitHub wiki, or wait for the Gitbook route?

Add the gather/take construct

Add the gather/take construct from Perl6.

var arr = gather { take "item" };

The construct should support nesting and recursion correctly.

Obfuscated example in "Mastering Sidef"

(:«2 A 4 H 1 J 3 ...)[1..4]map{static(ß)=+<tsu rehton fedi
rekca>,.+(ß<<1pop.reverse+(.len ?32.chr :%\,\))}.'join'say

It must have worked at one point in August 2015, like pre-0.08 (but I didn't go back any further), v0.08 doesn't mind syntax [1..4]map or <<1pop.reverse or ?ß.len , but it dies when calling reverse on the nil 1pop.

But what did it once do, and how would it be written in modern Sidef? (so that the Wiki doesn't have broken code)

NamedParam and Pair with variables

var (a, b)
var x = a:b # -> NamedParam

it's cool to see how exactly func(a: b) is implemented, but especially since NamedParam is not really useful outside a function call, maybe var:var should only be a NamedParam inside a function call, and be a Pair otherwise?

Or var:var should always create a Pair, but inside a function call it has a special I am a NamedParam, not a Pair value tag that the invocation understands. (This would need a change in ..., but I think it would break code that manually unpacks values into named parameters via sugared syntax)

Mostly I just wonder if this is intentional behaviour, it's not so bad to leave the "inconsistency" for var:var since 2:3 (usefully) gives Complex.

Global symbol "$n55919824" requires explicit package name (did you forget to declare "my $n55919824"?)

>> func sdn(n) { var b = [0]*n.len; var a = n.chars; a.each { |i| b[i] := 0 ++ }; a.join == b.join; }
=> func (n) { #`(sdn|56572880) ... }
>> sdn
syntax error at (eval 37) line 5, near "])"
=> nil
>> sdn 3
syntax error at (eval 38) line 5, near "])"
=> nil
>> sdn(4)
syntax error at (eval 39) line 5, near "))"
>> { var b = [0]*n.len; var a = n.chars; a.each { |i| b[i] := 0 ++ }; a.join == b.join; }
Global symbol "$n55919824" requires explicit package name (did you forget to declare "my $n55919824"?) at (eval 40) line 5.
Global symbol "$n55919824" requires explicit package name (did you forget to declare "my $n55919824"?) at (eval 40) line 5.
=> nil

That doesn't seem intentional. The code for func sdn(n) { ... } is from Rosetta Code: Self-describing Numbers

What's slow about this algorithm in Sidef?

The game is to write a toy digit-by-digit common logarithm (log10) function; I'm using Sidef's arbitrary precision to test the algorithm on non-hardware numbers.

The algorithm is from http://brics.dk/RS/04/17/BRICS-RS-04-17.pdf, but the algorithm isn't hugely important here.

The function in Sidef is

func log10_ (x, g) {
  const times = g*x.to_s.len
  var k = x
  gather {
    for (^ times) {
      const s = k.to_s
      const d = (s.chars.slice(1, s.index(".")).len - 1)
      take d
      k = ((k / (10**d)) ** 10)
      say k
    }
  }
}

say log10(1234.56)
say "---"
say log10_(1234.56, 2) # getting 2*6 digits of the logarithm

The equivalent code in Python is

def log10_1p(x, g):
    logdigits = []
    s = str(x)
    x = float(x)
    for _ in range(g * len(s)):
        s = str(x)
        logdigits.append(len(s[1 : s.index(".") or len(s) - 1]))
        x = (x / (10 ** logdigits[-1])) ** 10
        print(x)
    return logdigits

print(log10_1p(1234.56, 3)) # getting 3*6 digits of the logarithm

The output from Python is

8.22473693827674
1416511689.4062471
32.52382591129096
132439.11735410485
16.602090509224485
159.08446495477853
103.8192091772769
[...]
[3, 0, 9, 1, 5, 1, 2, 2, 0, 1, 6, 2, 7, 7]

real	0m0.062s

When running the Sidef code the output is

3.0915122016278
---
8.22473693827675
1416511689.4062604015717
32.523825911294
132439.117354229694
16.602090509381
159.0844649697746
[...]

The k and x intermediate values are the same from Python and Sidef so the Sidef code must be a correct version of the algorithm.

After 159, the Sidef code slows down, allocates almost 6GB of memory and Perl crashes -- the program never completes.

There are two main implementation differences between CPython and Sidef.

  1. Python strings are immutable, Sidef Strings are (I think) mutable. This might mean Sidef is less efficient.

  2. Python (usually) uses hardware floats or a very similar implementation, not GMP-style bignums. This is probably where most of the slowdown comes from.

Basically I just want to know, is it a bug that what seems to be very simple code is very slow, or am I mis-using Sidef?

I'm using Sidef-3.17/bin/sidef -O2 -c -o logs.pl logs.sidef && perl logs.pl to compile (-P option has no effect on speed) and perl 5, version 26, subversion 1 (v5.26.1) built for x86_64-linux-gnu-thread-multi.

Add the "?" unary prefix operator

Add the ? unary prefix operator and test its argument in boolean context and return true or false.

?1;  # returns: true
?0;  # returns: false

run the tests in scripts/Tests?

make test runs the install-time tests in ./t, but doesn't seem to run the Sidef scripts in scripts/Tests

RELEASE_TESTING=1 make test runs manifest.t but that doesn't actually run any of the .sf tests either.

find scripts/Tests/ -name '*.sf' -exec bin/sidef {} \; works fine, but I was wondering if i missed a canonical way.

Slurpy parameters appear to be broken

I think the doc is outdated,

Alternatively, by using a named variable in the form of :name, the arguments are collected inside an hash:

func f(:pairs) {
   say pairs      #=> Hash(a=>1, b=>2)
}
f(a => 1, b => 2)
>> f(a => 1, b => 2)                                                            
a
=> true

or:

>> func a(:k) { k }                                                            
=> func (*k) { #`(a|94509123145096) ... }
>> a(g => 1, r => "ok")                                                          
=> g
>> var x = a(g => 1, r => "ok")                                                    
=> g
>> x.class                                                                      
[AUTOLOAD] Undefined method `g.class' called from main()
=> 
>> x.methods                                                                    
[AUTOLOAD] Undefined method `g.methods' called from main()
=> 
>> x.new                                                                        
[AUTOLOAD] Undefined method `g.new' called from main()

The same result when f and a are declared with *pairs or *k instead of the :.

In both cases, the returned value, obviously not a Hash, appears to be an instantiation of a new object with the name of the first argument as its typename. The other arguments have gone into the aether. Surely this isn't intentional.

Also, the syntax for calling a func name(:collect_params) { } (using hash-style =>) is kind of impractical (as (x => y) isn't even a concrete object to the user code), and should IMO be consolidated with the NamedParam system, which could be even more useful in this case.

Imagine if we could write

func bar(:kw_args) {
  say kw_args
}
bar(a: 1, a_random_arg: "ok", [k: 12, t:14]...)
# -> Hash(a => 1, k => 12 ....

Making :kw_args into simply a form of *args that understands NamedParam would probably also simplify the implementation.

Hash literal indexing doesn't work inside class methods

>> class A { has Hash pi = Hash() ; method e { say self.pi{:name} } }           
=> Sidef::Runtime23::main::A
>> var a = A()                                                                  
=> Sidef::Runtime24::main::A=HASH(0x561f3d7957b0)
>> a.pi.append("name", "cat")                                                   
=> Hash("name" => "cat")
>> a.e                                                                          
Hash("name" => "cat")
=> true

>> var hash = Hash()                                                            
=> Hash()
>> hash{:name} = "cat"                                                          
=> cat
>> hash{:name}                                                                  
=> cat

(3.50) if you have a method in a class that returns self.member{:key} where member is a Hash, the string-indexing operation doesn't work and the entire hash is returned instead.

Actually it doesn't matter if you assign the hash to a local first (var p = self.pi; return p{:name}) or use the return keyword, this {"key"} / {:key} syntax is a no-op inside class methods.

Of course, thankfully you can still get the item by hash.item("key") or hash.fetch("key") but this is definitely wrong.

Add support for function closures (PHP-like)

Add support for explicitly defined closures. Maybe in the same way as PHP 5.3+ does it.

func accumulator(sum){
   func (n) <- sum {      # uses variable "sum"
      sum += n;
   }
};

var acc = accumulator(1);
acc(2);
accumulator(0);           # should not affect "acc"
say acc(3);               # should print 6 (the result of: 1+2+3)

Indexable String?

It's kind of weird that Sidef strings can't be indexed like "abc"[0] I think, I guess I'm just not used to it coming from Python, but most other languages have this property too.

Or is it preferred / intended to always say str.chars or str.split("") instead of trying to use String as Array?

Add support for multi functions and multi methods (Perl6-like)

Implementation idea:

  • add multi functions as elements inside an array (when multilple functions are declared in the same scope with the same name) and decide which function to call at runtime (with low overhead).
  • use the multi keyword (or find a better one (def?), or keep using the func and method keywords)

Code:

func test(a is String){
    say "got a string: #{a}";
};

func test(n is Number) {
    say "got a number: #{n}";
};

say test("sidef");
say test(42);

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.