Took me a few months, though, but mostly because I was too lazy and my DSL is still pretty buggy, has poor debugging support and long compilation times (takes about 30 seconds to reload source file). Anyway, this proves, that writing a game in Lisp is relatively easy, even for a single person.
>>6
It isn't ready. I did this game project just to see DSL in action, so now I'll redo a few things, like replacing "|>" with "|", making && and || work like in BASH and considering "::" operator instead of `if`, because I had tons of bash-like pipes all over the code, so optimizing them looks like a nice goal.
Name:
Anonymous2011-04-09 6:17
considering "::" operator instead of `if`
minF f a b -> a<b | f a b :: f b a
instead of
minF f a b -> if a<b (f a b) (f b a)
Good job. Is the game fully functional? How many lines of code is it?
You should still post the DSL implementation if you actually want people to be able to read your code. It's not like any of us want it for our own personal use, it's mostly to be able to read your posts.
Name:
Anonymous2011-04-09 7:21
>>10 How many lines of code is it?
1600 lines of code.
Good job. Is the game fully functional?
It loads maps from commercial game. Units, spells, buildings, transports - everything works. No player AI. No GUI.
>>11
I'm calling bullshit on this, yet a part of me really wants to believe. Wait, how long (in lines) is the DSL implementation?
Name:
Anonymous2011-04-09 7:45
>>10
Yes, just post the implementation -- unfinished or not, if you can write Warcraft 2 in it, it's probably done enough. Maybe start a github. Is there any documentation?
Name:
Anonymous2011-04-09 8:36
i miss the autism threads
Name:
Anonymous2011-04-09 9:17
>>12
I used a pretty general data structure, which allowed me to reuse most of the code for everything. For example, units, buildings, projectiles, actions, spells, icons and upgrades could be all processed by the same code.
This is how I define area bombardment spell "Blizzard"
layer=5 air=ye dirs=1 show="attack" ucost=["mana"=25]
range=12 effect=["wound" [0 10]] area=[2 2] shards=10 offset=[~4 ~4] splash=1
nonRMB=ye do=ye?
anims=["move"='((1 2 11) (1 2 10) (1 2 11))
"death"='((2 6) (3 6))]
It's cost checked by the same code, that checks resources for new buildings and unit training. Pathfinding, animations, drawing - all reused.
>>16
Not exactly Lisp, but a DSL written in Lisp, who the author keeps calling Lisp.
As for useful stuff in Lisp, I've written quite a few tools in CL for personal and not-so-personal usage, and I've been content with them. Any language can be used to make useful stuff, especially powerful high-level languages.
Name:
Anonymous2011-04-09 9:54
>>17
It's not even a ``DSL", it's a general purpose language implemented in Lisp. Calling it Lisp is the same as calling Python C just because one of its implementations is happen to be written in C.
>>18
Apparently he can still call CL from his implementation, but then you can use an FFI in any modern high-level language to call code written in other languages, except in this case, his code expands to CL code... However, there is a Python implementation written in CL, and if you wanted, you could write inline CL in that Python implementation, just like you can write inline assembly in some C implementations... Your point still stands about it being a separate language.
Name:
Anonymous2011-04-09 12:08
Has anyone made a game with The Land Of Lisp?
Name:
Anonymous2011-04-09 14:43
Minsky clicked the same unit several times.
To which the Sussman queried ``Why do you click the same unit several times?'',
``So he will say \"Stop clicking me!\"'' Minsky replied.
>>20
I can call CL using DSLs syntax. Though, it's problematic to reference non-uppercase symbols
Here is a C-style for-loop macro, one of cases of which expands into CL code
// for (i:0; i<6; !i+1) say i
e:m:for #($@v; $@c; $@i) @body ->
do $@v (cl progn (while (and $@(map ['`!` ?] c))
!$body $@(map ['`!` ?] i)))
; x 'in xs @body -> fe {$x->$@body} $xs
Name:
Anonymous2011-04-09 18:56
>>29
Also, DSL uses CPS, and CL uses usual stack, so invoking continuation will break this `for` macro and lead to nasty glitches.
1. Post a Warcraft 2 screenshot
2. Claim you reimplemented the game in Lisp
3. Watch /prog/ go crazy
4. ???
5. PROFIT!
Name:
Anonymous2011-04-09 23:10
>>31
No. I always hated stack. But some people believe, that C++-like RAII and unwind-protect are so important, that you can sacrifice continuations for them. It's just stupid, when you have garbage collection. If you want insure resource release, just set a watch-dog timer, that'll release resource after some time of disuse.
Name:
Anonymous2011-04-09 23:13
>>33
btw, watchdogs are a very powerful way to avoid deadlocks.
Name:
Anonymous2011-04-09 23:14
>>34
one can even allow for race conditions to exist, when he sure, that watchdog'll resolve them.
>>33
Global garbage collected heap environments like Java or .NET are literally garbage. Global heaps do not scale well for highly parallel systems. Fortunately, it's not like retards who can't manage their own memory are also good at concurrency.
Stick to your garbage collected toy languages.
Name:
Anonymous2011-04-10 0:53
>>36
stick to your over 9000 lines of code, that segfaults every few minutes.
int main() {
printf("Hi %s", NIGGERFUCK);
return 0;}
Name:
Anonymous2011-04-10 1:29
>>37
I use unit and regression testing coupled with sound idiomatic programming to limit critical failures in my software to a near zero probability. In fact, I would argue that most of my C/C++ software has far less bugs than most of the crap I see churned out by Java/C#/FIOC/Haskell/etc. developers.
>>41
It's in the standard, optional, but in the standard. Sepples is garbage collected.
Enjoy your toy garbage collected linear-bounded tarpit.
Name:
Anonymous2011-04-10 2:34
>>39 unit and regression testing coupled with sound idiomatic programming
Sounds time consuming and overly complicated, when in dymaic language you can have working program with little effort.
>>43 dymaic language
Nope. Nope. And more nope. Dynamic languages actually require a lot more unit and regression testing than static languages, to overcome type and identifier name resolution being resolved at runtime, whereas with static languages those types of bugs are caught at compile time and don't need runtime tests.
If you're using dynamic languages, you absolutely at least better have a regression test suite for any non-hobbyist project. Sure, dynamic languages are great for putting together one-off scripts and fire and forget code, but when it comes to maintaining and evolving a code base, dynamic languages can be painful without a proper test suite in place.
This is a well known problem of dynamic languages in the industry, and it seems only that amateurs and hobbyists aren't aware of this inherent problem.
In fact, pretty much any seasoned dynamic typing programmer will consider your code written in a dynamic language to be broken unless it has some automated unit tests.
>>47 identifier name resolution being resolved at runtime
What the fuck. (define (hax anus)
(my anus)) # compile: unbound identifier in modulein: my
Name:
Anonymous2011-04-10 5:33
>>47
In practice, you need to run program once and check its features and you don't have to care about udefined/untyped cases.
Name:
Anonymous2011-04-10 5:35
>>49
So, my LISP programs work, even if half of identifiers aren't binded yet.
Name:
Anonymous2011-04-10 5:38
>>48
That works in scheme or CL, but in FIOC, FFOC, Ruby and other hipster languages that us duck typing, until a function/method is actually ran, it's body is not fully evaluated.
>>51
Guess why they suck and are called toy languages.
Name:
Anonymous2011-04-10 5:42
>>48
This means, that you can't use global variables, without declaring them statically. Scheme is a statically typed language.
Name:
Anonymous2011-04-10 5:45
>>52
Yep. Static binding is inconvinient in REPL, where you spend most time during Lisping, so strong-typing and early binding makes Lisp not acceptable Lisp. Would be nice to have Lisp with weak typing, like BASH, where everything is a string.
Name:
Anonymous2011-04-10 5:48
>>54
Also, there are no undefined variables in BASH, they just hold empty strings.
>>53-55
Retardation is not /prog/-related. You may want to go back to /b/, now.
Name:
Anonymous2011-04-10 5:53
>>56
And everybody else went and chased static. And they've been doing it like crazy. And they've, in my opinion, reached the theoretical bounds of what they can deliver, and it has FAILED. These static type systems, they're WRONG. Wrong in the sense that when you try to do something, and they say: No, category theory doesn't allow that, because it's not elegant... Hey man: who's wrong? The person who's trying to write the program, or the type system?
Name:
Anonymous2011-04-10 5:54
Monad is just one of typeclasses. And a typeclass is some abstract entity, that allows concrete types to use some functions. And the nature of these functions depends on a typeclass of a concrete type, and how these functions implemented for a concrete type depends on the embodiment of the typeclass of that type. For example, monad Maybe is a type, computations, embedded into a monad of which, return either result, embedded into one of its data constructors, or a second data constructor - Nothing.
>>57
One retarded at time, please. Now it's the static-typed C/C++ fanboy faggot moment. Come back later.
Name:
Anonymous2011-04-10 5:59
More precisely, polytypic functions capture families of polymorphic functions in one single template de nition. Instances of a polytypic function for speci c algebraic types
can be generated automatically by a compiler following the denitional structure of the types. However, the de nitional structure of an abstract type is, for maintainability
reasons, logically hidden and, sometimes, even physically unavailable
>>36-60
Please stick to the topic. If you feel you have an interesting topic to discuss please utilize existing threads which are about the topic or create a new one if they do not exist.
Name:
Anonymous2011-04-10 13:37
>>61
Thread successfully derailed. Suck my cock, ,,faggot''.
>>74
Not exactly. I now have to write "X lt Y" instead of "X < Y". At least `lt` is a message, so it can be overloaded, by something like: invertedInteger X = (lt Y = X gt Y)
Name:
Anonymous2013-03-18 20:09
>>75
Oh, now that's a downside. Can't you replace the < with { or ( or something?
>>76
(), [] and {} already reserved for more frequent stuff, while comparison operators are four times less used than if/else block, despite my use of pattern-matching where possible. I.e. less-than operator is less important than the `map` function, which is the most used function, deserving a single letter name `m`, if not it's own operator. Bitwise functions are not getting their operators at all, so no << or >> cryptic crap: Just (A xor B shl C)
Name:
Anonymous2013-03-18 20:47
>>77
What contexts? My language has no undeclared global variables, because they are confusing: i.e. toplevel acts as a big let, and all files you want as part of package must be explicitly included with compiler directive. So a main file of C/C++ compiler package could look like:
$(say 'compiling C/C++ compiler...') //would be executed at compile time
say 'loading C/C++ compiler...' //would be executed on package load
@include lexer parser expander optimizer generator assembler
>>79
For instance, the context of the character < in #include <frozenvoid.h> is different to the one in if (a < b). The compiler knows that < means different things in different places. Limiting yourself to a one-to-one mapping between symbols and functions is silly.
>>84
It's an example, use your brain instead of picking out the irrelevant details so you don't have to respond properly.
Wait, does Symta even have lexical scoping? It wouldn't surprise me if it didn't. Have any scoping whatsoever, I mean. You do seem that clueless.
Name:
Anonymous2013-03-19 8:26
>>81
No. Reader reads <...> as simple ("<>" (...)) and if `>` is missing, it would be a read-time error. Of course macro can treat this ("<>" (...))
>>86
Symta does have lexical scoping, but I also use it to implement OOP. X and Y in (X:1 | Y:2 | X+Y) or (X:1 | Y:2 | sum = X+Y) wont be seen outside of (...), but in case of `sum = X+Y`, (...) gives closure with method `sum`. This provides encapsulation. Packages are implemented the same way, just to make reasoning about them easier (I was confused by Common Lisp's eval-when mess).
Name:
Anonymous2013-03-19 8:28
>>87
I.e. Symta is a context free language, which should make parsing easier.
>>90
<A in <A (<B = C>) has no left-hand side.
Even D < A < B = C > would work because after D it should expect an operator, not another operand.
There are also various precedence rules you could apply.
>>91 <A in <A (<B = C>) has no left-hand side.
Usually <...> is part of some larger expression, like [X <A < B = C> Y]
Even D < A < B = C > would work because after D it should expect an operator, not another operand.
How about (list D < A < B = C >)? Why not (list (D < A) (< B = C >))?
Name:
Anonymous2013-03-19 9:55
>>91
What about (list < A < B = C >)? It will be parsed as ((list < A) ..)