Atom_lang
I remember Euphoria.. the programming language.
This is not that.. but the inspiration came from there.
# frozen_string_literal: true
require './atom'
require './lang'
l = Lang.new
l << [3, 8, 11, 21, 9]
until l.empty? do p l>1 end
# 3
# 8
# 11
# 21
# 9
l >> [1,2,3] << [4,5,6] # [1, 2, 3, 4, 5, 6]
res = l & ->{ it.even? } | ->{ Atom.new(it * 2) }
p res # => [(4/1), (8/1), (12/1)]
p res | -> { (it * Math::PI).rat(2) } # => [(88/7), (201/8), (377/10)]
this is atom Link to heading
class Atom < Numeric
include Comparable
attr_reader :val
def initialize(val) = (@val = val.to_r)
def <=>(o) = (@val <=> (o.is_a?(Atom) ? o.val : o))
def coerce(o) = [Atom.new(o), self]
[:+, :-, :*, :/, :%, :**].each {|op|
define_method(op) { |o| Atom.new(@val.send(op, (o.is_a?(Atom) ? o.val : o))) }
}
[:to_f, :to_i, :to_r].each {|op| define_method(op) { @val.send(op) } }
# rationalize to n decimal places (dp)
# (see (3.14/2).rationalize(0.001) # for reference)
def rationalize(dp) = Atom.new(@val.rationalize(10**-dp))
alias_method :rat, :rationalize
def to_s = ( @val.to_f.to_s )
end
this is lang Link to heading
class Lang
attr_reader :ar
def initialize = ( @ar = [] )
def <<(obj) = ( self.tap { @ar.push(*Array(obj)) } )
def >>(obj) = ( self.tap { @ar.unshift(*Array(obj)) } )
def <(n=1) = ( n == 1 ? @ar.pop : @ar.pop(n) )
def >(n=1) = ( n == 1 ? @ar.shift : @ar.shift(n) )
def |(fn) = Lang.new.tap { it << @ar.map(&fn) }
def &(fn) = Lang.new.tap { it << @ar.filter(&fn) }
def inspect = ( @ar.map(&:to_r) )
def empty? = @ar.empty?
end