d2jsp
Log InRegister
d2jsp Forums > Off-Topic > Computers & IT > Programming & Development > Crystal-lang Fan Thread
12Next
Add Reply New Topic New Poll
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Mar 28 2016 06:06pm
http://crystal-lang.org/

Language Goals

  • Ruby-inspired syntax.
  • Statically type-checked but without having to specify the type of variables or method arguments.
  • Be able to call C code by writing bindings to it in Crystal.
  • Have compile-time evaluation and generation of code, to avoid boilerplate code.
  • Compile to efficient native code.


Still in alpha, but it seem fully functional besides a few kinks that need to be worked out about arrays and hashes.

There is also an awesome-list that has a bunch of usefull shards (crystal bindings to C code). Such bindings and other libraries include:

  • Api builders
  • Caching
  • Database Drivers
  • HTTP
  • Virtualization


And many more.

https://github.com/veelenga/awesome-crystal

------------------------------------------------------------------------------------------

Fairly excited about it, even though it still is in alpha and was kind of a pain to compile/install.

Using this test case:

Code
def prime_test(max)
primes = [] of Int32
(1..max).each {|num|
if (2..num-1).all? {|denom| num%denom >0}
primes.push(num)
end
}
end

prime_test 100000


Ruby completed the task in 73 seconds and crystal completed it in 3 seconds. That was a speed reduction of 24 times, just by compiling the same ruby code with the crystal compiler. The only thing that needed changing is that in crystal they have not concluded on how they wanted to handle the types of an array/hash so they specifically have to be typed until the figure it out.

This post was edited by AbDuCt on Mar 28 2016 06:07pm
Member
Posts: 32,925
Joined: Jul 23 2006
Gold: 3,804.50
Mar 28 2016 06:09pm
CoR coming up next?

This post was edited by carteblanche on Mar 28 2016 06:10pm
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Mar 28 2016 06:27pm
Quote (carteblanche @ Mar 28 2016 08:09pm)
CoR coming up next?


Funny. Surprisingly there are many frameworks similar to rails available.
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Mar 30 2016 11:06pm
Reading through the docs more on crystal and there are a few things I learned about it today.

First thing is they have a XML/HTML parser built directly into the standard library which is based off libxml2. This means I don't have to use nokogiri from ruby any more.

Here is the basic spec that they use to test the functionality:

https://raw.githubusercontent.com/ryanworl/crystal/462dae1ccfee2a6a2e6d25f8814556d88fc015c9/spec/std/xml/html_spec.cr

More or less intuitive for roaming around source. And since it is using the libxml2 library XPaths are also supported by default.

Next I found that they have already implemented concurrent tasks and channels so that you can concurrently distribute tasks among fibers which each has its own 8MB stack (same as threads).

Usage is simple as well:

Code
channel = Channel(Int32).new

spawn do
puts "Before first send"
channel.send(1)
puts "Before second send"
channel.send(2)
end

puts "Before first receive"
value = channel.receive
puts value # => 1

puts "Before second receive"
value = channel.receive
puts value # => 2

#output
Before first receive
Before first send
1
Before second receive
Before second send
2


As you can see concurrent tasks are cooperative, meaning that they should relinquish their time by themselves when there is nothing to do. For instance if one Fiber is IO bound it will relinquish its time so that another fiber may do some work. In this instance the main thread executes "before first receive" and waits for IO on the channel and gives up control. From there the spawned fiber prints "before first send" and outputs data to the channel and gives up control back to the main thread. Then the cycle repeats for the second set of calls.

More information can be found here:

http://crystal-lang.org/docs/guides/concurrency.html

And finally some random crystal benchmarks against many popular languages:

https://github.com/kostya/benchmarks

As you can see crystal rivals the speed of C/++ in many of the test cases only being short of a few seconds to a few milliseconds difference. Compared against other popular languages (python, ruby mri, C#, Java) crystal runs many times faster.

It also has support for raw pointer manipulation, but who the fuck cares about that.

This post was edited by AbDuCt on Mar 30 2016 11:09pm
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Apr 1 2016 06:23pm
One thing I miss is a centralized dependency manager, or rather just being able to look for packages and add them to the project.

In crystal there is the Shard manager, although all it does is download and place the libraries/packages in your project directory. There is no way to search for packages based on wild card strings unfortunately. This is because they are still trying to figure out if they should have a centralized package repo, or if the manager should fetch directly from the github. At the moment the only way to get packages is to either clone the repo yourself, or specify the version and github repo in the shard.yml file and let crystal/shard pull them in. That is if you already know the name of the repo.

I mean I don't care either way, I just want to search for some damn packages without using google-fu.

Member
Posts: 62,204
Joined: Jun 3 2007
Gold: 9,039.20
Apr 1 2016 06:50pm
Quote (AbDuCt @ Apr 1 2016 06:23pm)
One thing I miss is a centralized dependency manager, or rather just being able to look for packages and add them to the project.

In crystal there is the Shard manager, although all it does is download and place the libraries/packages in your project directory. There is no way to search for packages based on wild card strings unfortunately. This is because they are still trying to figure out if they should have a centralized package repo, or if the manager should fetch directly from the github. At the moment the only way to get packages is to either clone the repo yourself, or specify the version and github repo in the shard.yml file and let crystal/shard pull them in. That is if you already know the name of the repo.

I mean I don't care either way, I just want to search for some damn packages without using google-fu.


Write one for them
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Apr 1 2016 07:05pm
Quote (j0ltk0la @ Apr 1 2016 08:50pm)
Write one for them


They already have the dependency manager, they just don't know if they want to host all the sources in one place, or each on a seperate github owned by the authors or what.

TBH they should just have a central github that has the links to all the packages supported so that their manager can just download/pull packages from the owners github.

Kinda the best of both worlds I guess.
Member
Posts: 6,114
Joined: Jul 11 2007
Gold: 35.78
Apr 2 2016 10:14pm
Im thinking about getting into a newer language, how would you compare crystal to go-lang?
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Apr 2 2016 10:34pm
Quote (implite @ Apr 3 2016 12:14am)
Im thinking about getting into a newer language, how would you compare crystal to go-lang?


I've never used go-lang before so I can't say to much, likewise with crystal.

Although from the docs and crystal API it appears it is an almost fully featured standard library: http://crystal-lang.org/api/

This includes the standards like arrays, strings, ints, sockets, IO all the way to benchmarking, crypto, digests, concurrency, pipes, and even built in OAUTH2 support.

I believe go-lang is much more mature than crystal from what I've read. Crystal is still very much in alpha, and has a much smaller following than go-lang. Although if you know ruby very well, crystal is a natural progression since it shares much of the same thought process, features, and syntax.

Both may be good toy languages, but if you are looking for something which may be more suited for production work, I'd choose go-lang over crystal just because of the larger user base. On the flip side crystal is roughly always faster (only by a few milliseconds to a few seconds in the benches I've seen) than GO. Although that doesn't mean much at all.

This post was edited by AbDuCt on Apr 2 2016 11:02pm
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Apr 3 2016 09:58am
New crystal release: 0.15.0

  • (breaking change) ! has now its meaning hardcoded in the language. If you defined it for a type it won't be invoked as a method anymore.
  • (breaking change) nil? has now its meaning hardcoded in the language. If you defined it for a type it won't be invoked as a method anymore.
  • (breaking change) typeof is now disallowed in alias declarations
  • Added crystal tool format --check to check that source code is properly formatted
  • crystal play (playground) added workbooks support, as well as improvements and stabilizations
  • Added Tempfile.dirname (thanks @DougEverly)
  • Added Path#resolve method in macros
  • {{...}} arguments to a macro call are now expanded before macro invocation (#2392)
  • Special variables ($~ and $?) are now accessible after being defined in blocks (#2194)
  • Some bugs and regressions fixed


What this means for the language:

Hard coding ! and nil? allows the language to be more flexible and more ruby like. Not to mention is fixes some trivial compile errors that some people may often overlook.

For instance say we want to find the occurrence of a sub-string inside another string, or print "Not found" if not found.

Code
# `String#index` returns an Int32 if the index is found, or Nil if not
index = "some_word".index(ARGV[0])
if index
puts "Found at character number #{index + 1}"
else
puts "Not found"
end


The way the compiler interpreters this code is that if index is a truthful value (not nil, false, or null pointer) then the value of index inside the "then" branch can only be of type Int32, so the operation "index + 1" compiles fine.

Code
index = "some_word".index(ARGV[0])
if !index
puts "Not found"
else
puts "Found at character number #{index + 1}"
end


In this segment of code, which does the exact same thing has a flaw though due to the ! (and also the .nil? method) which is that they were able to be user definable. Compiling this code would result in:

Code
Error in ./file.cr:14: undefined method '+' for Nil (compile-time type is Int32?)

puts "Found at character number #{index + 1}"


Logically in the "else" branch to us, there is no way index can be nil due to the ! operator however because ! was able to be user redefined the compiler could not make that guarantee that ! actually meant what ! used to be. For instance, if someone redefined ! for what ever reason to be a double not (!nil is true, !!nil is false) then it was possible to fool the branch logic into executing the "else" branch which would in turn cause all kinds of problems when a nil value had the addition applied to it.

So to fix this, they hard coded the behavior of ! and .nil? so that they can not be user redefined and this allows constructing logical statements easier since now you don't have to work around compiler quirks to get your code to compile.

This post was edited by AbDuCt on Apr 3 2016 10:00am
Go Back To Programming & Development Topic List
12Next
Add Reply New Topic New Poll