Ich plane, ein verbessertes GolfScript für noch kürzere Programme zu schreiben, die mehr können. Dies ist keine Herausforderung. Es ist eine Bitte um Feedback und Tipps, was ich tun soll. (siehe tags)
Ich bin mir nicht sicher, ob dies Community Wiki sein soll. Wenn Sie so denken, markieren Sie es einfach, damit ein Moderator es konvertiert :)
Diese Sprache wird GolfScript sehr ähnlich sein. Es ist immer noch in Ruby geschrieben. Es gibt jedoch einige Unterschiede:
- Wird
`
als Zeichenkettenbegrenzer verwendet, da es sich um ein ungewöhnliches Zeichen handelt, sodass weniger Escapezeichen erforderlich sind. (Ein anderes Zeichen kann seine Funktion ersetzen, wie#
(dazu später mehr)).\`
einem Backtick\\
zu entkommen, einem Backslash zu entkommen, und es gibt keine anderen Escape-Sequenzen. Wenn Sie eine neue Zeile benötigen, kleben Sie einfach eine tatsächliche wörtliche Zeile in die Zeichenfolge. - Die Verwendung von Ruby's
Rational
für Gleitkommazahlen mit willkürlicher Genauigkeit ist einer der Hauptfehler von GolfScript. - Die Möglichkeit, Typen in andere Typen zu konvertieren. Sie können beispielsweise einen Block in eine Zeichenfolge konvertieren.
- Reguläre Ausdrücke. Wahrscheinlich erstellt mit
"..."
. Die Operatoren werden auch für sie überlastet. Zum Beispiel"\W"~{`Invalid: non-word character`}{`OK`}if
. Wird automatisch ausgeführt, wenn von einer Variablen wie Blöcken gedrückt wird. - Datei- und Datumsobjekte, um mehr Dinge zu tun, die in GolfScript nicht möglich waren. Diese haben keine Literale, aber Funktionen zum Initialisieren, wie zB
`file.txt`fl
(der Name der Funktion zum Erstellen von Dateien kann sich ändern). - Haschs vielleicht, aber da bin ich mir nicht sicher. Sollte ich?
- Der Helfer kann noch mehr. Zum Beispiel
`http://example.com`net
für den Netzwerkzugriff (erneut kann dernet
Betreiber umbenannt werden).rb
um einen String als Ruby-Code auszuführen. Es wird noch viel mehr davon geben; Vorschläge willkommen. - Keine Kommentare, so dass
#
für etwas anderes verwendet werden kann. Wenn Sie einen Kommentar wünschen,`comment here`;
wird gut funktionieren. (Vielleicht#
kann`
's die Funktion ersetzen ) - Es wird komplett neu geschrieben, so dass das Hinzufügen von Funktionen viel einfacher wird. Grundsätzlich ist der Code besser lesbar. (Haben Sie die GolfScript-Quelle gesehen?
:/
) - Es wird auf Github sein, damit gemeinsam daran gearbeitet werden kann. Ich werde es unter MIT lizenzieren oder so.
- Keine abschließende Newline, daher funktionieren betrügerische Quines: P
Und ich setze diese Punkte auseinander, weil ich denke, dass sie die drastischsten und hilfreichsten Änderungen sind (außer vielleicht das Hinzufügen von Gleitkommazahlen):
- Es werden viele Ruby-Funktionen eingebaut. Zum Beispiel
shuffle
(was abgekürzt werden kannsf
) (früher 9 Zeichen ),tr
(früher 14 Zeichen ),sample
(sm
früher.,rand=
),flatten
(fl
früher ???) usw. - Es wird wie Rebmu gemixt. Zum Beispiel können Sie jetzt
~:a0<{0a-}aIF
(unter Verwendung eines Buchstabenvariablennamens) anstatt~:$0<{0$-}$if
(die Sortierfunktion zu überschreiben). (Beispiel von hier ). Beachten Sie, dass auf diese Weise die Groß- und Kleinschreibung nicht berücksichtigt wird und in Variablennamen keine Zahlen zulässig sind. Dies ist meiner Meinung nach in Ordnung, da es eine Golfsprache ist: P - Es wird ein Debugging haben. Ich werde die Möglichkeit hinzufügen, ein Flag bereitzustellen, das Array-Begrenzer, Element-Begrenzer usw. angibt, die Ausgabe von Zahlen (rational, float oder int?), Schrittweise Anweisungen durchläuft, jedes Token tokenisiert und ausgibt, anstatt das Programm auszuführen. etc.
Meine Frage lautet also: Was gibt es zu verbessern? Was denkst du sollte ich hinzufügen?
Irgendwelche anderen Ideen dafür, bevor ich anfange, es zu codieren?
quelle
Antworten:
Flexibles I / O
Golfscript kann derzeit nicht für interaktive Programme verwendet werden. Ich schlage vor , einige Funktionen für explizite Eingabe hinzugefügt werden ( das heißt
readline
,getchar
und Freunde). Der Interpreter sollte prüfen, ob das Programm diese verwendet, bevor es ausgeführt wird.Wenn das Programm keine Eingabefunktionen aufruft, sollte sich der Interpreter wie bei Golfscript verhalten.
Ich würde nicht erwarten, dass der Interpreter Eingabefunktionen in ausgewertetem Code erkennt, der zur Laufzeit generiert wird, aber wenn er das irgendwie kann, ein dickes Lob.
quelle
Kürzere Einbauten
Einzelzeichen-Aliase für alle eingebauten Befehle, die diese nicht haben. Ich würde
base
viel mehr verwenden, wenn es nur so wäreB
.quelle
b
als Variablennamen verwenden? Immer noch; gute Idee; Sie müssen nur daran denken, diesen Namen nicht zu verwenden, wenn Sie die Funktion verwenden möchten, und wenn Sie die Funktion nicht verwenden, hat dies keinerlei Auswirkungen auf Sie.^
oder$
) als Variablennamen verwenden. Es macht dieses Problem nicht schlimmer. Außerdem habe ich Aliase vorgeschlagen, um die Abwärtskompatibilität zu ermöglichen. Sie müssten also nur den längeren Namen verwenden, wenn Sie dem kürzeren Alias etwas anderes zugewiesen hätten.Z
fürzip
wäre auch sehr nützlich.#include
und"#{IO.read'lib'}"~
ist zu lang).mylang -Llibname somefile.ext
.Kombinierter Div-Mod
Das ist ein bisschen mehr Nische als einige der Vorschläge, aber wenn sie auf zahlentheoretische Programmen arbeiten selbst finde ich häufig eine Operation zu wollen , die zwei ganze Zahlen erscheinen
a
undb
aus dem Stapel und Stössea/b
unda%b
. (Derzeit ist dies1$1$/@@%
).quelle
dvm
für DiV-Mod. Danke für all die Ideen :-) +1Zahlen
Ändern Sie das Lexer so, dass führende 0 nicht Teil einer Zahl ist:
_
Stattdessen sollten auch negative Zahlen geschrieben werden:quelle
0 100-
für das Negative 100. +1~
. ZB -1 ist0~
. Dies verlängert eine kleine Anzahl von Zahlen um ein Zeichen, beseitigt jedoch die mäßig häufige Notwendigkeit von Leerzeichen danach-
.{0\-}:~;
(~
negativ zu machen) undnot
bitweise zu verwenden (genau wieand or xor
)?Zugriff auf den gesamten Stapel
GolfScript ist eine stapelbasierte Sprache, aber der Zugriff auf alle Elemente außer den drei obersten auf dem Stapel ist auf
<integer>$
das Kopieren des n-ten Elements beschränkt. Es wäre nützlich, so etwas wie den PostScript-roll
Befehl zu haben, damit es einfacher ist, mit mehr als drei "Live" -Variablen zu arbeiten.Idealerweise gibt es eine Ein-Argument- und eine Zwei-Argument-Version, aber wenn nicht genügend Namen in der Nähe sind, sollte das Ein-Argument eine Ein-Zeichen-Version bevorzugen.
Die Ein-Argument-Eins nimmt nur die Anzahl der zu würfelnden Gegenstände. ZB
1 roll
macht nichts;2 roll
ist gleichbedeutend mit\
;3 roll
ist gleichbedeutend mit@
;4 roll
und für höhere Nummern gibt es kein vorhandenes Äquivalent; das nächstmögliche ist so etwas wie(und das behandelt nicht einmal Nicht-Ganzzahlen an bestimmten Positionen des Stapels oder aktiv
[
und bricht mit ziemlicher Sicherheit auch innerhalb von Schleifen).Die Zwei-Argumente-Variante benötigt ebenfalls einen Betrag, um zu würfeln.
a b roll2
ist äquivalent zu{a roll}b*
.quelle
rotate
. Sie sollten dies in der CW-Antwort bearbeiten.roll
drehe nur das Array, oder?CJam
Ich habe "ein verbessertes GolfScript" implementiert und es heißt CJam - http://sf.net/p/cjam. In
der zweiten Version (Version 0.6) enthält es bereits viele, wenn nicht die meisten der hier diskutierten Funktionen. Ich werde versuchen, sie aufzulisten:
`
als Zeichenkettenbegrenzer - nein, aber es werden Zeichenketten in doppelten Anführungszeichen mit minimalem Escape-Zeichen verwendet (\
nur Escape- Zeichen\
und"
)`http://example.com`net
-"example.com"g
#
für etwas anderes verwendet,"comments like this";
mr
er
_,mr=
Debugging - Nur Stapel-Traces und
ed
Operator zum Anzeigen des Stapelsflexible I / O - ja, aber nur explizite Eingabe
b
= Sockel,z
= Reißverschluss-
- ja, aber nicht mit_
;1 2-3
->1 2 -3
;1 2m3
->-1 3
t
md
m*
et
ea
e<
,e>
z
(GolfScript hatabs
nicht gefehlt):+
,:*
c
(konvertiert in ein Zeichen, keine Zeichenkette){}/
:
davon verbraucht, was gespeichert ist - nein>=
,<=
- nein, verwenden<!
,>!
1$1$
CJam hat viel mehr Funktionen, siehe https://sourceforge.net/p/cjam/wiki/Operators/
quelle
Ändern Sie den Lexer
Der GolfScript-Lexer behandelt einen Ruby-Bezeichner (alles, was mit dem regulären Ausdruck übereinstimmt
[_a-zA-Z][_a-zA-Z0-9]*
) als einen einzigen Token. Wenn es stattdessen[a-zA-Z]+
als Token behandelt wird , entsteht ein integriertes Token, auf das_
eine Alpha-Variable von einer Literal-Ganzzahl gefolgt werden kann, ohne Leerzeichen zu trennen.quelle
[a-z]+|[A-Z]+
zum Mushen, also ist der Unterstrich kostenlos. Dies ist jedoch eine interessante und sehr einzigartige Idee! +1Unicode-Aliase
Befehle mit mehreren Zeichen können Unicode-Aliase enthalten. Dies würde die Punktzahl einsparen, wenn die Punktzahl in Zeichen und nicht in Bytes gezählt wird.
quelle
Stabile Sorte
Die
$
eingebauten Blöcke sollten eine stabile Sortierung ausführen.quelle
Array-Set-Operator
Können wir dafür ein eingebautes Gerät zur Verfügung stellen?
quelle
Einzelzeichen-IDs
Es ist nicht so, dass eine Code-Golf-Lösung zu viele Variablen enthalten würde. Und es würde Platz sparen.
quelle
% als eingebaut für Produkt
quelle
Regex-Unterstützung
Der Mangel an Regex-Unterstützung hat mich in einer für das Golfen konzipierten Sprache immer als merkwürdig empfunden. Es wäre toll zu haben
<string> <string> <string> y
(auch bekannttr
als Perls One-Char-Alias)<string> <string> <string> s
(Ersatz)<string> <string> <block> s
(durch Rückruf ersetzen)<string> <string> m
(Spiel)quelle
Builtins für aktuelles Datum / Uhrzeit
Es ist derzeit sehr eigenartig, Datum und Uhrzeit mithilfe von Ruby-Auswertungen abzurufen.
quelle
Make |, & and ^ built-ins do something useful on blocks
E.g.
<array/string> <block> |
can be used as index functionAny ideas for
<array/string> <block> &
or<array/string> <block> ^
?quelle
array block =
do now?"0<" {0<} =
.array block =
for "select by predicate",
.A way to turn symbols back into code blocks
Currently, we can bind code blocks to symbols with
:
, but there's no way to reverse the process: executing a symbol bound to a code block just executes the block.I can see a couple of ways to implement this:
add new syntax, e.g.
#foo
to push the value offoo
to the stack, even if it's a code block, oradd an operator to expand every symbol in a code block, so that (using
_
as the new operator), e.g.{2*}:dbl; {dbl dbl}_
would produce{2* 2*}
.I can see advantages to both methods. The latter could substitute for the former, at the cost of two extra chars (
{foo}_
instead of#foo
), but I can see some potential applications for the former syntax where those two chars would be prohibitive (e.g. usingarray #func %
instead ofarray {func} %
).Meanwhile, the former syntax could be used to replace the latter if there was a convenient way to somehow iterate over the tokens in a code block (which could be useful on its own, anyway).
In either case, I'd propose that expanding symbols that are bound to native built-ins (i.e. implemented in Ruby code) should return some kind of stub that could be called to obtain the functionality of the built-in, while being either impossible or just unlikely to be overridden. For example
#$
(or{$}_
) could return e.g.{builtin_dollar}
, wherebuiltin_dollar
would contain the actual implementation of the$
built-in (and#builtin_dollar
or{builtin_dollar}_
should just return{builtin_dollar}
itself).This would allow built-ins to be redefined without losing access to their functionality (see my earlier suggestion), so that if I, say, for some reason wanted to swap the meanings of
$
and@
, I could just do#$ #@ :$; :@;
(or{$}_ {@}_ :$; :@;
).quelle
_
operator should do if the code block contains variable assignments. The obvious thing would be to just leave any:symbol
tokens untouched and expand anything else, but this would cause_
to break any code using local variables. Making it not break such code might be impractically complicated, though.[[1] [2] [3]] _ -> [1 2 3]
.2:A;{1:A;A}_
?{1:A;2}
(or, to be technical,{1:A builtin_semicolon 2}
if the built-in expansion feature was included). If some kind of "local variable exclusion" feature was included, it might plausibly evaluate to just{1:A;A}
.{builtin_1 :A builtin_semicolon 2}
.Variable preset with command line args
Unfortunately, there isn't any char left unassigned, but maybe we can use
A
for that?quelle
_
is available. Perhaps that? Anyway, yes, golfscript needs a way of taking cmd line args +1Native Ruby functions that I should implement
This is Community Wiki; feel free to edit and add the functions you think I should implement!
Format: "
nativeFunctionName
(nameInMyLanguage
)"shuffle
(sf
)tr
(tr
)sample
(sm
)quelle
Take features from APL and HQ9+ too!
quelle
Clearly separating built-ins
e.g. capitals : built-ins ; making B for base feasable
quelle
{-}:+
.Local variables / closures
One thing I really miss in GolfScript is the ability to temporarily change the value of a symbol.
In particular, there's currently no way to temporarily override the meaning of a "primitive" built-in: once you, say, redefine
$
, you're never going to sort anything in that program again. (Well, not without writing your own sort implementation, at least.) It would be really nice to be able to say, for example, that in this code block$
means something else, but still keep the normal meaning elsewhere.Related to the above, it would be nice to bind symbols in a code block to their current value. Sure, I can write, say,
{$-1%}:rsort
and be able to usersort
to sort and reverse an array, but that works only as long as the definition of$
(or-1
or%
) doesn't change, since myrsort
function is still calling the global symbol$
. It would be nice to be able to say "letrsort
do what$-1%
currently does, even if those symbols are later redefined."In particular, the standard library could use this kind of binding. It's kind of surprising to realize that, say, changing
n
changes the behavior ofputs
, or that redefining!
completely messes upxor
. (Then again, some caution should be exercised here, since, in particular, the ability to change the behavior ofputs
turns out to be turns out to be the only way to avoid printing a final newline in the current version of GS.)Edit: Being able to turn symbols back into code blocks would go a long way towards implementing this functionality. In particular, the
{foo}_
syntax suggested in that answer would effectively perform one level of static binding by expanding all symbols in a code block. Combine that with a fixpoint combinator for deep static binding, and Bob's your uncle...quelle
rsort
do what$-1%
currently does, even if those symbols are later redefined" So Emmental?More built-in functions
Make all the single-letter variables a-z and A-Z perform some generic, useful function. Some built-ins that are lacking:
{+}*
when you can doS
? You have 52 functions to work with here!x1 y1 x2 y2 --> abs(x2-x1)+abs(y2-y1)
. Now it'd have to be@-A@@-A+
ifA
is a built-in absolute value. Granted this only came up caues of my most recent post but I always figured that'd be a good way to expand golfscript: write down what functions would be handy to have, collect them, and add them as built-ins.chr
).{}/
):
that consumes what is stored. This would have to not get 'stuck' to identifiers to be useful.>=
,<=
1{\}{|}if
to something like1?\?|if
1$
,2$
,3$
,4$
,5$
\.@.@\
quelle
It'd be nice if the value written or computed in the last line of a function was automatically returned
quelle