I'm currently working on a small interpreter written in Forth. For a small optimization, I'm trying to have a word which creates compiled words. For example, something which behaves like this:
: creator ( -- a )
:noname ( u -- u )
10 + ;
;
10 creator execute .
>> 20 ok
I tried several approaches so far and non worked (naïve like above, switching in interpretive mode, trying to compile a string of Forth source). Is this actually possible?
When you write compiling words, you have to be very careful about which words execute at compile time, and which execute at runtime. In this case, 10 + runs at compile time, and will not be compiled into you :noname definition.
I believe this is what you want:
: creator ( -- xt ) :noname ( n1 -- n2 )
10 postpone literal postpone + postpone ; ;
Also note that you may use CREATE DOES> in many cases. E.g. if you want your creator to accept a number which is used by the child word:
: creator ( n1 "name" -- ) create ,
does> ( n2 -- n1+n2 ) # + ;
Related
I have several large logical expressions (length upto 300K) of the form -
( ( ( 1 ) and ( 5933 or 561 or 1641 ) ) or ( ( 71 or 1 or 15 or 20 ) and ( 436 ) ) or ( ( 398 or 22 or 33 ) ) )
that are parsed using Boost Spirit (as shown in the example here - Boolean expression (grammar) parser in c++)
The parsing takes more than a minute for each expression.
I would like to do the parsing offline which results in an expression represented by -
typedef boost::variant <var,
boost::recursive_wrapper<unop <op_not> >,
boost::recursive_wrapper<binop<op_and> >,
boost::recursive_wrapper<binop<op_or> >
> expr;
This expression needs to be propagated to multiple machines for real-time evaluation against inputs. These machines cannot be made to spend the necessary time for the initial parsing.
Is it possible to propagate the parsed expression in the boost::variant representation above via Boost Interprocess managed_mapped_file? I have tried doing this via a unique_ptr of the expression object and was able to write to a memory mapped file, but evaluation against this object on the other hand resulted in a segmentation fault.
Note that I have also tried boost serialization, which fails for very large expressions.
Looking forward to any advice around this.
Thanks!
The SciTE editor comes with embedded Lua scripting engine having access to the text buffer of the editor. This makes it possible to extend SciTE's functionality with tools programmed in Lua and started from the Tools Menu. One such tool available from here:
http://lua-users.org/wiki/SciteSortSelection
is a tool for sorting of selected lines in alphabetical order.
Annoying for me was/is that it doesn't sort lines containing numbers in their numerical order but like this:
1
111
2
222
3
333
where I would rather expect:
1
2
3
111
222
333
Google and Co. are not of much help here as there is to my knowledge no solution to this problem available yet online. It is also not that easy to find and deeply understand the Lua documentation for table.sort(). So the question for a knowledgeable Lua programmer would be, what is the best way to patch the existing Lua script code, so that numbers (and also lines with text in case of leading spaces) become sorted as expected and the Lua code for this task runs so fast, that even sorting of huge files (50 MByte and more) won't take much time?
Your expectation is wrong. You said the algorithm is supposed to sort the texts alphabetically and that is exactly what it does.
For Lua "11" is smaller than "2".
I think you would agree that "aa" should come befor "b" which is pretty much the same thing.
If you want to change how texts are sorted you have to provide your own function.
The Lua reference manual says:
table.sort (list [, comp])
Sorts list elements in a given order, in-place, from list[1] to
list[#list]. If comp is given, then it must be a function that
receives two list elements and returns true when the first element
must come before the second in the final order (so that, after the
sort, i < j implies not comp(list[j],list[i])). If comp is not given,
then the standard Lua operator < is used instead.
Note that the comp function must define a strict partial order over
the elements in the list; that is, it must be asymmetric and
transitive. Otherwise, no valid sort may be possible.
The sort algorithm is not stable: elements considered equal by the
given order may have their relative positions changed by the sort.
So you are free to implement your own comp function to change the sorting.
By default table.sort(list) sort list in ascending order.
To make it sort in descending order you call:
table.sort(list, function(a,b) return a > b end)
If you want to treat numbers differently you can do something like this:
t = {"111", "11", "3", "2", "a", "b"}
local function myCompare(a,b)
local a_number = tonumber(a)
local b_number = tonumber(b)
if a_number and b_number then
return a_number < b_number
end
end
table.sort(t, myCompare)
for i,v in ipairs(t) do
print(v)
end
which would give you the output
2
3
11
111
a
b
Of course this is just a quick and simple example. A nicer implementation is up to you.
Below what I finally came up with myself. It's sure a quick and dirty solution which slows the already slow
( compared to jEdit [Plugins]->[Text Tools]->[Sort Lines] or to bash command line 'sort -g' )
process of sorting huge buffers of text lines, but it is at least there for use and works as expected. For the sake of completeness here the entire section of code currently present in my Lua Startup Script for SciTE:
-- =============================================================================
-- Sort Selected Lines (available in MENU -> Tools):
-- -----------------------------------------------------------
-- Specify in .SciTEUser.properties:
-- command.name.2.*=# Sort Selected Lines '
-- command.subsystem.2.*=3
-- command.mode.2.*=savebefore:no
-- command.2.*=SortSelectedLines
-- # command.shortcut.2.*=Ctrl+2 # Ctrl+2 is DEFAULT for command.2.*
function lines(str)
local t = {}
local i, lstr = 1, #str
while i <= lstr do
local x, y = string.find(str, "\r?\n", i)
if x then t[#t + 1] = string.sub(str, i, x - 1)
else break
end
i = y + 1
end
if i <= lstr then t[#t + 1] = string.sub(str, i) end
return t
end
-- It was an annoying for me that using table.sort(buffer) in Lua
-- didn't sort numbers with leading spaces in their numerical order.
-- Using following comparison function helps to avoid that problem:
function compare(a,b)
return a:gsub(" ", "0") < b:gsub(" ", "0")
-- If 'compare' is not used ( table.sort(buf) )
-- Lua uses implicit for sorting (see Lua tutorial):
-- return a < b
-- so changing the provided return statement to this above
-- would be enough to restore sorting to how it was before
end
function SortSelectedLines()
local sel = editor:GetSelText()
if #sel == 0 then return end
local eol = string.match(sel, "\n$")
local buf = lines(sel)
table.sort(buf, compare)
--table.foreach (buf, print) --used for debugging
local out = table.concat(buf, "\n")
if eol then out = out.."\n" end
editor:ReplaceSel(out)
end
-- ---------
-- :Sort Selected Lines
-- -----------------------------------------------------------------------------
I don't understand Factor's functors. I guess it would help to first understand what a "functor" is.
Google says:
a function; an operator.
In Factor, all functions (words) are operators, and are first-class. (In fact, I can't think of much in Factor that isn't first class). This definition isn't so helpful.
Wikipedia says:
Functor may refer to:
...
In computer programming:
function object used to pass function pointers along with its state
...
In Haskell a Functor describes a generalisation of functions that perform mapping operations
The page for "function object" says:
an object to be invoked or called as if it were an ordinary function, usually with the same syntax (a function parameter that can also be a function).
So a functor is a first-class function? This is nothing special, and anyways words and quotations and stuff are already first-class in Factor.
Factor Functors have weird syntax that reminds me of generics or something.
resource:unmaintained/models/combinators/templates/templates.factor:
FROM: models.combinators => <collection> #1 ;
FUNCTOR: fmaps ( W -- )
W IS ${W}
w-n DEFINES ${W}-n
w-2 DEFINES 2${W}
w-3 DEFINES 3${W}
w-4 DEFINES 4${W}
w-n* DEFINES ${W}-n*
w-2* DEFINES 2${W}*
w-3* DEFINES 3${W}*
w-4* DEFINES 4${W}*
WHERE
MACRO: w-n ( int -- quot ) dup '[ [ _ narray <collection> ] dip [ _ firstn ] prepend W ] ;
: w-2 ( a b quot -- mapped ) 2 w-n ; inline
: w-3 ( a b c quot -- mapped ) 3 w-n ; inline
: w-4 ( a b c d quot -- mapped ) 4 w-n ; inline
MACRO: w-n* ( int -- quot ) dup '[ [ _ narray <collection> #1 ] dip [ _ firstn ] prepend W ] ;
: w-2* ( a b quot -- mapped ) 2 w-n* ; inline
: w-3* ( a b c quot -- mapped ) 3 w-n* ; inline
: w-4* ( a b c d quot -- mapped ) 4 w-n* ; inline
;FUNCTOR
The documentation is extremely sparse on these. What are they? When should I use them?
Don't think of functors as that 'They're named "functors" to annoy category theory fanboys and language purists.' :)
Their use is mainly to generate boilerplate or template code. Just like C++ templates are an optimization feature because generic dispatch can be slow, so are Factor functors.
Example here:
USING: functors io lexer namespaces ;
IN: examples.functors
FUNCTOR: define-table ( NAME -- )
name-datasource DEFINES-CLASS ${NAME}-datasource
clear-name DEFINES clear-${NAME}
init-name DEFINES init-${NAME}
WHERE
SINGLETON: name-datasource
: clear-name ( -- ) "clear table code here" print ;
: init-name ( -- ) "init table code here" print ;
name-datasource [ "hello-hello" ] initialize
;FUNCTOR
SYNTAX: SQL-TABLE: scan-token define-table ;
You can now write SQL-TABLE: person and Factor will create the words clear-person, init-person and person-datasource for you.
When to use them? I think never unless you have performance problems that warrants their use. They are very bad for grepability.
in my little code example I have random values for the variable testvar%bed when I compile with -O2 optimization.
gfortran -O2 test.F90
edit to make the problem more clear:
So the problem is, that I print testvar%bed, and it shows random junk, that changes on every run (unprintable characters, like �����). It should be printing bed.
This only happens on some systems. On
debian gcc 4.9.1 -- okay
osx gcc 4.9.1 -- okay
ubuntu gcc 4.9.1 -- random values
arch gcc 4.9.2 -- random values
This happens if the function is called two times in the code. If I comment out the second call, everything is okai again.
I can also "kind of fix" this if I put an arbitrary print statement at the end of the function.
edit in reply to #tkoenig
The problem does not occur with only -O1 or without any optimizations. It does occur with -O1 -fgcse but not with only -fgcse. Only using -ffrontend-optimize alone does not rise the error.
What am I missing?
program testbug
implicit none
integer, parameter :: STRLEN = 256
type :: ncVarnames_t
! variables names for the different ice models
character (len=STRLEN) :: surf
character (len=STRLEN) :: x, y
character (len=STRLEN) :: bed
character (len=STRLEN) :: thick
end type ncVarnames_t
type (ncVarnames_t) :: testvar
type (ncVarnames_t) :: testvar2
print *, "hello"
testvar = get_ncVarnames ("test")
testvar2 = get_ncVarnames ("test")
print *, trim(testvar%surf)
print *, trim(testvar%bed)
print *, trim(testvar%bed)
print *, trim(testvar%surf)
contains
type (ncVarnames_t) function get_ncVarnames (model) result (v)
character(len=*), intent(in) :: model
! type (ncVarnames_t) :: v
select case (model)
case ("test")
! test model
v%x = 'x'
v%y = 'y'
v%surf = 'surf'
v%bed = 'bed'
case ("pism")
! pism data
v%x = 'x'
v%y = 'y'
v%surf = 'usurf'
v%bed = 'topg'
case default
print *, "unknown model, please use one of [test pism sico]"
stop
end select
end function get_ncVarnames
end program testbug
Looks like a gfortran/gcc bug, which may need some special circumstances to trigger (which is why not everybody appears to be able to reproduce it).
I have also reproduced this and submitted PR 65504. This is a regression against 4.8, so it should receive special attention. Fixes should also be backported to 4.9.
Workaround (as analzyed in the PR): Use -fno-dse.
I have a program that I am trying to make faster, mostly for the sake of making it faster to learn more about Haskell. For comparison I have written the same program in C and have a 4x speed improvement. I expected faster from C, but that kind of difference makes me think I have something wrong.
So I have profiled the Haskell code and over 50% of the time is spent producing the formatted String for output. So just this section takes more than my entire C program. The function is similar to this:
display :: POSIXTime -> [(Int, Centi)] -> IO()
display t l = putStrLn $ t_str ++ " " ++ l_str
where
t_str = show . timeToTimeOfDay . unsafeCoerce $ (t `mod` posixDayLength)
l_str = intercalate " " $ map displayPair l
displayPair (a,b) = show a ++ " " ++ show b
Notes about the code:
The unsafeCoerce is to convert NominalDiffTime to DiffTime which have the same type but this is faster than toRational . fromRational which I had been using.
Centi is defined in Data.Fixed and is a number with 2 decimal places
TimeOfDay is as you would expect just hours, minutes and seconds (stored with picosecond accuracy).
`mod` posixDayLength is so we just get the time of day ignoring which day it is (because that is all I care about ... it is from a timestamp and I know that it had to be today - I just care what time today!).
I have tried using ShowS (String -> String) to concatenate results and this is not significantly faster.
I have tried using Data.Text but that makes the code slower (presumably spends too much time packing strings).
I used to have the putStrLn in a separate function but it is faster here (less thunks built up? but why?).
Is there an easy way to improve output performance in Haskell that I'm missing?
For producing output the highest performance can be found by avoiding String in favour of either a ByteString or Text. In order to build the output there is a special data type called Builder. There is a good description with examples in the [ByteString] hackage description.
The resulting code looks like this:
import Data.Monoid
display :: POSIXTime -> [(Int, Centi)] -> IO()
display t l = hPutBuilder stdout $ t_str <> space <> l_str
where
space = (byteString . pack) " "
t_str = (byteString . pack . show . timeToTimeOfDay . unsafeCoerce) $ (t `mod` posixDayLength)
l_str = foldr <> space $ map displayPair l
displayPair (a,b) = intDec a <> space <> (byteString . pack . show) b
The builder data type builds up chunks that it will then concatenate in O(1) in to a buffer for the output. Unfortunately, not all types have a builder for them and only the base types. So for outputting the others the only solution is to pack the string ... or perhaps to write a function to create a builder (and add it to the library?).