I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

# Sierpinski curve

Sierpinski curve is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Produce a graphical or ASCII-art representation of a Sierpinski curve of at least order 3.

## AutoHotkey

Translation of: Go

Requires Gdip Library

`SierpinskiW	:= 500SierpinskiH	:= 500level 		:= 5cx		:= SierpinskiW/2cy		:= SierpinskiHh		:= cx / (2**(level+1))Arr := []squareCurve(level)xmin := xmax := ymin := ymax := 0for i, point in Arr{	xmin := A_Index = 1 ? point.x : xmin < point.x ? xmin : point.x	xmax := point.x > xmax ? point.x : xmax	ymin := A_Index = 1 ? point.y : ymin < point.y ? ymin : point.y	ymax := point.y > ymax ? point.y : ymax}SierpinskiX := A_ScreenWidth/2 - (xmax-xmin)/2	, SierpinskiY := A_ScreenHeight/2 - (ymax-ymin)/2for i, point in Arr	points .= point.x - xmin + SierpinskiX "," point.y - ymin + SierpinskiY "|"points := Trim(points, "|")gdip1()Gdip_DrawLines(G, pPen, Points)UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height)return ; ---------------------------------------------------------------lineTo(newX, newY) {	global	Arr[Arr.count()+1, "x"] := newX-SierpinskiW/2+h	Arr[Arr.count()  , "y"] := SierpinskiH-newY+2*h	cx := newX	cy := newY}; ---------------------------------------------------------------sierN(level) {	global	if (level = 1) {		lineTo(cx+h, cy-h)	; lineNE()		lineTo(cx, cy-2*h)	; lineN()		lineTo(cx-h, cy-h)	; lineNW()	}	else{		sierN(level - 1)		lineTo(cx+h, cy-h)	; lineNE()		sierE(level - 1)		lineTo(cx, cy-2*h)	; lineN()		sierW(level - 1)		lineTo(cx-h, cy-h)	; lineNW()		sierN(level - 1)	}}; ---------------------------------------------------------------sierE(level) {	global	if (level = 1) {		lineTo(cx+h, cy+h)	; lineSE()		lineTo(cx+2*h, cy)	; lineE()		lineTo(cx+h, cy-h)	; lineNE()	}	else {		sierE(level - 1)		lineTo(cx+h, cy+h)	; lineSE()		sierS(level - 1)		lineTo(cx+2*h, cy)	; lineE()		sierN(level - 1)		lineTo(cx+h, cy-h)	; lineNE()		sierE(level - 1)	}}; ---------------------------------------------------------------sierS(level) {	global	if (level = 1) {		lineTo(cx-h, cy+h)	; lineSW()		lineTo(cx, cy+2*h)	; lineS()		lineTo(cx+h, cy+h)	; lineSE()	}	else {		sierS(level - 1)		lineTo(cx-h, cy+h)	; lineSW()		sierW(level - 1)		lineTo(cx, cy+2*h)	; lineS()		sierE(level - 1)		lineTo(cx+h, cy+h)	; lineSE()		sierS(level - 1)	}}; ---------------------------------------------------------------sierW(level) {	global	if (level = 1) {		lineTo(cx-h, cy-h)	; lineNW()		lineTo(cx-2*h, cy)	; lineW()		lineTo(cx-h, cy+h)	; lineSW()	}	else {		sierW(level - 1)		lineTo(cx-h, cy-h)	; lineNW()		sierN(level - 1)		lineTo(cx-2*h, cy)	; lineW()		sierS(level - 1)		lineTo(cx-h, cy+h)	; lineSW()		sierW(level - 1)	}}; ---------------------------------------------------------------squareCurve(level) {	global	sierN(level)	lineTo(cx+h, cy-h)	; lineNE()	sierE(level)	lineTo(cx+h, cy+h)	; lineSE()	sierS(level)	lineTo(cx-h, cy+h)	; lineSW()	sierW(level)	lineTo(cx-h, cy-h)	; lineNW()	lineTo(cx+h, cy-h)	; lineNE()} ; ---------------------------------------------------------------gdip1(){	global	If !pToken := Gdip_Startup()	{		MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system		ExitApp	}	OnExit, Exit	Width := A_ScreenWidth, Height := A_ScreenHeight	Gui, 1: -Caption +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop	Gui, 1: Show, NA	hwnd1 := WinExist()	hbm := CreateDIBSection(Width, Height)	hdc := CreateCompatibleDC()	obm := SelectObject(hdc, hbm)	G := Gdip_GraphicsFromHDC(hdc)	Gdip_SetSmoothingMode(G, 4)	pPen := Gdip_CreatePen(0xFFFF0000, 2)}; ---------------------------------------------------------------gdip2(){	global	Gdip_DeleteBrush(pBrush)	Gdip_DeletePen(pPen)	SelectObject(hdc, obm)	DeleteObject(hbm)	DeleteDC(hdc)	Gdip_DeleteGraphics(G)}; ---------------------------------------------------------------Exit:gdip2()Gdip_Shutdown(pToken)ExitAppReturn `

## C++

Output is a file in SVG format. The curve is generated using the Lindenmayer system method.

`// See https://en.wikipedia.org/wiki/Sierpi%C5%84ski_curve#Representation_as_Lindenmayer_system#include <cmath>#include <fstream>#include <iostream>#include <string> class sierpinski_curve {public:    void write(std::ostream& out, int size, int length, int order);private:    static std::string rewrite(const std::string& s);    void line(std::ostream& out);    void execute(std::ostream& out, const std::string& s);    double x_;    double y_;    int angle_;    int length_;}; void sierpinski_curve::write(std::ostream& out, int size, int length, int order) {    length_ = length;    x_ = length/std::sqrt(2.0);    y_ = 2 * x_;    angle_ = 45;    out << "<svg xmlns='http://www.w3.org/2000/svg' width='"        << size << "' height='" << size << "'>\n";    out << "<rect width='100%' height='100%' fill='white'/>\n";    out << "<path stroke-width='1' stroke='black' fill='none' d='";    std::string s = "F--XF--F--XF";    for (int i = 0; i < order; ++i)        s = rewrite(s);    execute(out, s);    out << "'/>\n</svg>\n";} std::string sierpinski_curve::rewrite(const std::string& s) {    std::string t;    for (char c : s) {        if (c == 'X')            t += "XF+G+XF--F--XF+G+X";        else            t += c;    }    return t;} void sierpinski_curve::line(std::ostream& out) {    double theta = (3.14159265359 * angle_)/180.0;    x_ += length_ * std::cos(theta);    y_ -= length_ * std::sin(theta);    out << " L" << x_ << ',' << y_;} void sierpinski_curve::execute(std::ostream& out, const std::string& s) {    out << 'M' << x_ << ',' << y_;    for (char c : s) {        switch (c) {        case 'F':        case 'G':            line(out);            break;        case '+':            angle_ = (angle_ + 45) % 360;            break;        case '-':            angle_ = (angle_ - 45) % 360;            break;        }    }} int main() {    std::ofstream out("sierpinski_curve.svg");    if (!out) {        std::cerr << "Cannot open output file\n";        return 1;    }    sierpinski_curve s;    s.write(out, 545, 7, 5);    return 0;}`
Output:

See: sierpinski_curve.svg (offsite SVG image)

## Factor

Works with: Factor version 0.99 2020-08-14
`USING: accessors kernel L-system sequences ui ; : curve ( L-system -- L-system )    L-parser-dialect    { "G" [ dup length>> draw-forward ] } suffix >>commands    [ 45 >>angle ] >>turtle-values    "F--XF--F--XF" >>axiom    {        { "X" "XF+G+XF--F--XF+G+X" }    } >>rules ; [ <L-system> curve "Sierpinski curve" open-window ] with-ui`

When using the L-system visualizer, the following controls apply:

Camera controls
Button Command
a zoom in
z zoom out
left arrow turn left
right arrow turn right
up arrow pitch down
down arrow pitch up
q roll left
w roll right
Other controls
Button Command
x iterate L-system

## Fōrmulæ

Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.

Programs in Fōrmulæ are created/edited online in its website, However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.

## Go

Library: Go Graphics
Translation of: Phix

A partial translation anyway which produces a static image of a SC of level 5, yellow on blue, which can be viewed with a utility such as EOG.

`package main import (    "github.com/fogleman/gg"    "math") var (    width  = 770.0    height = 770.0    dc     = gg.NewContext(int(width), int(height))) var cx, cy, h float64 func lineTo(newX, newY float64) {    dc.LineTo(newX-width/2+h, height-newY+2*h)    cx, cy = newX, newY} func lineN() { lineTo(cx, cy-2*h) }func lineS() { lineTo(cx, cy+2*h) }func lineE() { lineTo(cx+2*h, cy) }func lineW() { lineTo(cx-2*h, cy) } func lineNW() { lineTo(cx-h, cy-h) }func lineNE() { lineTo(cx+h, cy-h) }func lineSE() { lineTo(cx+h, cy+h) }func lineSW() { lineTo(cx-h, cy+h) } func sierN(level int) {    if level == 1 {        lineNE()        lineN()        lineNW()    } else {        sierN(level - 1)        lineNE()        sierE(level - 1)        lineN()        sierW(level - 1)        lineNW()        sierN(level - 1)    }} func sierE(level int) {    if level == 1 {        lineSE()        lineE()        lineNE()    } else {        sierE(level - 1)        lineSE()        sierS(level - 1)        lineE()        sierN(level - 1)        lineNE()        sierE(level - 1)    }} func sierS(level int) {    if level == 1 {        lineSW()        lineS()        lineSE()    } else {        sierS(level - 1)        lineSW()        sierW(level - 1)        lineS()        sierE(level - 1)        lineSE()        sierS(level - 1)    }} func sierW(level int) {    if level == 1 {        lineNW()        lineW()        lineSW()    } else {        sierW(level - 1)        lineNW()        sierN(level - 1)        lineW()        sierS(level - 1)        lineSW()        sierW(level - 1)    }} func squareCurve(level int) {    sierN(level)    lineNE()    sierE(level)    lineSE()    sierS(level)    lineSW()    sierW(level)    lineNW()    lineNE() // needed to close the square in the top left hand corner} func main() {    dc.SetRGB(0, 0, 1) // blue background    dc.Clear()    level := 5    cx, cy = width/2, height    h = cx / math.Pow(2, float64(level+1))    squareCurve(level)    dc.SetRGB255(255, 255, 0) // yellow curve    dc.SetLineWidth(2)    dc.Stroke()    dc.SavePNG("sierpinski_curve.png")}`

## Java

Translation of: C++
`import java.io.*; public class SierpinskiCurve {    public static void main(final String[] args) {        try (Writer writer = new BufferedWriter(new FileWriter("sierpinski_curve.svg"))) {            SierpinskiCurve s = new SierpinskiCurve(writer);            s.currentAngle = 45;            s.currentX = 5;            s.currentY = 10;            s.lineLength = 7;            s.begin(545);            s.execute(rewrite(5));            s.end();        } catch (final Exception ex) {            ex.printStackTrace();        }    }     private SierpinskiCurve(final Writer writer) {        this.writer = writer;    }     private void begin(final int size) throws IOException {        write("<svg xmlns='http://www.w3.org/2000/svg' width='%d' height='%d'>\n", size, size);        write("<rect width='100%%' height='100%%' fill='white'/>\n");        write("<path stroke-width='1' stroke='black' fill='none' d='");    }     private void end() throws IOException {        write("'/>\n</svg>\n");    }     private void execute(final String s) throws IOException {        write("M%g,%g\n", currentX, currentY);        for (int i = 0, n = s.length(); i < n; ++i) {            switch (s.charAt(i)) {                case 'F':                case 'G':                    line(lineLength);                    break;                case '+':                    turn(ANGLE);                    break;                case '-':                    turn(-ANGLE);                    break;            }        }    }     private void line(final double length) throws IOException {        final double theta = (Math.PI * currentAngle) / 180.0;        currentX += length * Math.cos(theta);        currentY -= length * Math.sin(theta);        write("L%g,%g\n", currentX, currentY);    }     private void turn(final int angle) {        currentAngle = (currentAngle + angle) % 360;    }     private void write(final String format, final Object... args) throws IOException {        writer.write(String.format(format, args));    }     private static String rewrite(final int order) {        String s = AXIOM;        for (int i = 0; i < order; ++i) {            final StringBuilder sb = new StringBuilder();            for (int j = 0, n = s.length(); j < n; ++j) {                final char ch = s.charAt(j);                if (ch == 'X')                    sb.append(PRODUCTION);                else                    sb.append(ch);            }            s = sb.toString();        }        return s;    }     private final Writer writer;    private double lineLength;    private double currentX;    private double currentY;    private int currentAngle;     private static final String AXIOM = "F--XF--F--XF";    private static final String PRODUCTION = "XF+G+XF--F--XF+G+X";    private static final int ANGLE = 45;}`
Output:

See: sierpinski_curve.svg (offsite SVG image)

## Julia

### Turtle procedural (lineto) version

Modified from Craft of Coding blog, Processing version

`using Luxor function sierpinski_curve(x0, y0, h, level)    x1, y1 = x0, y0    lineto(x, y) = begin line(Point(x1, y1), Point(x, y), :stroke); x1, y1 = x, y end    lineN() = lineto(x1,y1-2*h)    lineS() = lineto(x1,y1+2*h)    lineE() = lineto(x1+2*h,y1)    lineW() = lineto(x1-2*h,y1)    lineNW() = lineto(x1-h,y1-h)    lineNE() = lineto(x1+h,y1-h)    lineSE() = lineto(x1+h,y1+h)    lineSW() = lineto(x1-h,y1+h)    function drawN(i)        if i == 1            lineNE(); lineN(); lineNW()        else            drawN(i-1); lineNE(); drawE(i-1); lineN(); drawW(i-1); lineNW(); drawN(i-1)        end    end    function drawE(i)        if i == 1            lineSE(); lineE(); lineNE()        else            drawE(i-1); lineSE(); drawS(i-1); lineE(); drawN(i-1); lineNE(); drawE(i-1)        end    end    function drawS(i)        if i == 1            lineSW(); lineS(); lineSE()        else            drawS(i-1); lineSW(); drawW(i-1); lineS(); drawE(i-1); lineSE(); drawS(i-1)        end    end    function drawW(i)        if i == 1            lineNW(); lineW(); lineSW()        else            drawW(i-1); lineNW(); drawN(i-1); lineW(); drawS(i-1); lineSW(); drawW(i-1)        end    end    function draw_curve(levl)        drawN(levl); lineNE(); drawE(levl); lineSE()        drawS(levl); lineSW(); drawW(levl); lineNW()    end    draw_curve(level)end Drawing(800, 800)sierpinski_curve(10, 790, 3, 6)finish()preview() `

### LSystem version

`using Lindenmayer # https://github.com/cormullion/Lindenmayer.jl sierpcurve = LSystem(Dict("X" => "XF+G+XF--F--XF+G+X"), "F--XF--F--XF") drawLSystem(sierpcurve,    forward = 10,    turn = 45,    startingpen= (0.2, 0.8, 0.8),    startingx = -380,    startingy = 380,    startingorientation = π/4,    iterations = 5,    filename = "sierpinski_curve.png",    showpreview = true) `

## Mathematica / Wolfram Language

`Graphics[SierpinskiCurve[3]]`

## Nim

Translation of: C++

We produce a SVG file using same algorithm as the one of C++ version.

`import math type   SierpinskiCurve = object    x, y: float    angle: float    length: int    file: File  proc line(sc: var SierpinskiCurve) =  let theta = degToRad(sc.angle)  sc.x += sc.length.toFloat * cos(theta)  sc.y -= sc.length.toFloat * sin(theta)  sc.file.write " L", sc.x, ',', sc.y  proc execute(sc: var SierpinskiCurve; s: string) =  sc.file.write 'M', sc.x, ',', sc.y  for c in s:    case c    of 'F', 'G': sc.line()    of '+': sc.angle = floorMod(sc.angle + 45, 360)    of '-': sc.angle = floorMod(sc.angle - 45, 360)    else: discard  func rewrite(s: string): string =  for c in s:    if c == 'X':      result.add "XF+G+XF--F--XF+G+X"    else:      result.add c  proc write(sc: var SierpinskiCurve; size, length, order: int) =  sc.length = length  sc.x = length.toFloat / sqrt(2.0)  sc.y = 2 * sc.x  sc.angle = 45  sc.file.write "<svg xmlns='http://www.w3.org/2000/svg' width='", size, "' height='", size, "'>\n"  sc.file.write "<rect width='100%' height='100%' fill='white'/>\n"  sc.file.write "<path stroke-width='1' stroke='black' fill='none' d='"  var s = "F--XF--F--XF"  for _ in 1..order: s = s.rewrite()  sc.execute(s)  sc.file.write "'/>\n</svg>\n"  let outfile = open("sierpinski_curve.svg", fmWrite)var sc = SierpinskiCurve(file: outfile)sc.write(545, 7, 5)outfile.close()`
Output:

Same as C++ output.

## Perl

`use strict;use warnings;use SVG;use List::Util qw(max min); use constant pi => 2 * atan2(1, 0); my \$rule = 'XF+F+XF--F--XF+F+X';my \$S = 'F--F--XF--F--XF';\$S =~ s/X/\$rule/g for 1..5; my (@X, @Y);my (\$x, \$y) = (0, 0);my \$theta   = pi/4;my \$r       = 6; for (split //, \$S) {    if (/F/) {        push @X, sprintf "%.0f", \$x;        push @Y, sprintf "%.0f", \$y;        \$x += \$r * cos(\$theta);        \$y += \$r * sin(\$theta);    }    elsif (/\+/) { \$theta += pi/4; }    elsif (/\-/) { \$theta -= pi/4; }} my (\$xrng, \$yrng) = ( max(@X) - min(@X),  max(@Y) - min(@Y));my (\$xt,   \$yt)   = (-min(@X) + 10,      -min(@Y) + 10); my \$svg = SVG->new(width=>\$xrng+20, height=>\$yrng+20);my \$points = \$svg->get_path(x=>\@X, y=>\@Y, -type=>'polyline');\$svg->rect(width=>"100%", height=>"100%", style=>{'fill'=>'black'});\$svg->polyline(%\$points, style=>{'stroke'=>'orange', 'stroke-width'=>1}, transform=>"translate(\$xt,\$yt)"); open my \$fh, '>', 'sierpinski-curve.svg';print \$fh  \$svg->xmlify(-namespace=>'svg');close \$fh;`

See: sierpinski-curve.svg (offsite SVG image)

## Phix

Library: Phix/pGUI
`-- demo\rosetta\Sierpinski_curve.exw----  Draws curves lo to hi (simultaneously), initially {1,1}, max {8,8}--  Press +/- to change hi, shift +/- to change lo.--  ("=_" are also mapped to "+-", for the non-numpad +/-)--include pGUI.e Ihandle dlg, canvascdCanvas cddbuffer, cdcanvas integer width, height,        lo = 1, hi = 1atom cx, cy, h procedure lineTo(atom newX, newY)    cdCanvasVertex(cddbuffer, newX-width/2+h, height-newY+2*h)    cx = newX    cy = newYend procedure procedure lineN() lineTo(cx,cy-2*h) end procedureprocedure lineS() lineTo(cx,cy+2*h) end procedureprocedure lineE() lineTo(cx+2*h,cy) end procedureprocedure lineW() lineTo(cx-2*h,cy) end procedure procedure lineNW() lineTo(cx-h,cy-h) end procedureprocedure lineNE() lineTo(cx+h,cy-h) end procedureprocedure lineSE() lineTo(cx+h,cy+h) end procedureprocedure lineSW() lineTo(cx-h,cy+h) end procedure procedure sierN(integer level)   if level=1 then      lineNE()  lineN()      lineNW()   else      sierN(level-1)  lineNE()      sierE(level-1)  lineN()      sierW(level-1)  lineNW()      sierN(level-1)    end ifend procedure procedure sierE(integer level)   if level=1 then      lineSE()  lineE()      lineNE()    else      sierE(level-1)  lineSE()      sierS(level-1)  lineE()      sierN(level-1)  lineNE()      sierE(level-1)    end ifend procedure procedure sierS(integer level)   if level=1 then      lineSW()  lineS()      lineSE()    else      sierS(level-1)  lineSW()      sierW(level-1)  lineS()      sierE(level-1)  lineSE()      sierS(level-1)    end ifend procedure procedure sierW(integer level)   if level=1 then      lineNW()  lineW()      lineSW()    else      sierW(level-1)  lineNW()      sierN(level-1)  lineW()      sierS(level-1)  lineSW()      sierW(level-1)    end ifend procedure procedure sierpinskiCurve(integer level)   sierN(level)     lineNE()   sierE(level)     lineSE()   sierS(level)     lineSW()   sierW(level)     lineNW()end procedure function redraw_cb(Ihandle /*ih*/, integer /*posx*/, integer /*posy*/)    {width, height} = IupGetIntInt(canvas, "DRAWSIZE")    cdCanvasActivate(cddbuffer)    for level=lo to hi do        cx = width/2        cy = height        h = cx/power(2,level+1)        cdCanvasBegin(cddbuffer, CD_CLOSED_LINES)        sierpinskiCurve(level)        cdCanvasEnd(cddbuffer)    end for    cdCanvasFlush(cddbuffer)    return IUP_DEFAULTend function function map_cb(Ihandle ih)    cdcanvas = cdCreateCanvas(CD_IUP, ih)    cddbuffer = cdCreateCanvas(CD_DBUFFER, cdcanvas)    cdCanvasSetBackground(cddbuffer, CD_WHITE)    cdCanvasSetForeground(cddbuffer, CD_BLUE)    return IUP_DEFAULTend function function key_cb(Ihandle /*ih*/, atom c)    if c=K_ESC then return IUP_CLOSE end if    if find(c,"+=-_") then        bool bShift = IupGetInt(NULL,"SHIFTKEY")        if c='+' or c='=' then            if bShift then                lo = min(lo+1,hi)            else                hi = min(8,hi+1)            end if        elsif c='-' or c='_' then            if bShift then                lo = max(1,lo-1)            else                hi = max(lo,hi-1)            end if        end if        IupSetStrAttribute(dlg, "TITLE", "Sierpinski curve (%d..%d)",{lo,hi})        cdCanvasClear(cddbuffer)        IupUpdate(canvas)    end if    return IUP_CONTINUEend function procedure main()    IupOpen()     canvas = IupCanvas(NULL)    IupSetAttribute(canvas, "RASTERSIZE", "770x770")    IupSetCallback(canvas, "MAP_CB", Icallback("map_cb"))    IupSetCallback(canvas, "ACTION", Icallback("redraw_cb"))     dlg = IupDialog(canvas)    IupSetAttribute(dlg, "TITLE", "Sierpinski curve (1..1)")    IupSetCallback(dlg, "K_ANY", Icallback("key_cb"))     IupMap(dlg)    IupShowXY(dlg,IUP_CENTER,IUP_CENTER)    IupMainLoop()    IupClose()end procedure main()`

## Quackery

`  [ \$ "turtleduck.qky" loadfile ] now!   [ stack ]                      is switch.arg (   --> [ )   [ switch.arg put ]             is switch     ( x -->   )   [ switch.arg release ]         is otherwise  (   -->   )   [ switch.arg share     != iff ]else[ done      otherwise ]'[ do ]done[ ]    is case       ( x -->   )   [ \$ "" swap witheach       [ nested quackery join ] ] is expand     ( \$ --> \$ )   [ \$ "L" ]                      is L          ( \$ --> \$ )   [ \$ "R" ]                      is R          ( \$ --> \$ )   [ \$ "F" ]                      is F          ( \$ --> \$ )   [ \$ "G" ]                      is G          ( \$ --> \$ )   [ \$ "AFLGLAFRRFRRAFLGLA" ]     is A          ( \$ --> \$ )   \$ "FRRAFRRFRRAF"   5 times expand   turtle 1 8 turn   witheach    [ switch        [ char L case [ -1 8 turn  ]          char R case [  1 8 turn  ]          char A case [ ( ignore ) ]           otherwise [ 5 1 walk ] ] ]  -1 8 turn`
Output:

## Raku

(formerly Perl 6)

Works with: Rakudo version 2020.02
`use SVG; role Lindenmayer {    has %.rules;    method succ {        self.comb.map( { %!rules{\$^c} // \$c } ).join but Lindenmayer(%!rules)    }} my \$sierpinski = 'F--XF--F--XF' but Lindenmayer( { X => 'XF+G+XF--F--XF+G+X' } ); \$sierpinski++ xx 5; my \$dim = 640;my \$scale = 8;my \$dir = pi/4;my @points = (316, -108); for \$sierpinski.comb {    state (\$x, \$y) = @points[0,1];    state \$d = 0;    when 'F'|'G' { @points.append: (\$x += \$scale * \$d.cos).round(1), (\$y += \$scale * \$d.sin).round(1) }    when '+' { \$d -= \$dir }    when '-' { \$d += \$dir }    default { }} my \$out = './sierpinski-curve-perl6.svg'.IO; \$out.spurt: SVG.serialize(    svg => [        :width(\$dim), :height(\$dim),        :rect[:width<100%>, :height<100%>, :fill<black>],        :polyline[          :points(@points.join: ','), :fill<black>,          :transform("rotate(45, 320, 320)"), :style<stroke:#F7DF1E>,        ],    ],);`

See: Sierpinski-curve-perl6.svg (offsite SVG image)

## Rust

Program output is a file in SVG format.

`// [dependencies]// svg = "0.8.0" use svg::node::element::path::Data;use svg::node::element::Path; struct SierpinskiCurve {    current_x: f64,    current_y: f64,    current_angle: i32,    line_length: f64,} impl SierpinskiCurve {    fn new(x: f64, y: f64, length: f64, angle: i32) -> SierpinskiCurve {        SierpinskiCurve {            current_x: x,            current_y: y,            current_angle: angle,            line_length: length,        }    }    fn rewrite(order: usize) -> String {        let mut str = String::from("F--XF--F--XF");        for _ in 0..order {            let mut tmp = String::new();            for ch in str.chars() {                match ch {                    'X' => tmp.push_str("XF+G+XF--F--XF+G+X"),                    _ => tmp.push(ch),                }            }            str = tmp;        }        str    }    fn execute(&mut self, order: usize) -> Path {        let mut data = Data::new().move_to((self.current_x, self.current_y));        for ch in SierpinskiCurve::rewrite(order).chars() {            match ch {                'F' => data = self.draw_line(data),                'G' => data = self.draw_line(data),                '+' => self.turn(45),                '-' => self.turn(-45),                _ => {}            }        }        Path::new()            .set("fill", "none")            .set("stroke", "black")            .set("stroke-width", "1")            .set("d", data)    }    fn draw_line(&mut self, data: Data) -> Data {        let theta = (self.current_angle as f64).to_radians();        self.current_x += self.line_length * theta.cos();        self.current_y -= self.line_length * theta.sin();        data.line_to((self.current_x, self.current_y))    }    fn turn(&mut self, angle: i32) {        self.current_angle = (self.current_angle + angle) % 360;    }    fn save(file: &str, size: usize, order: usize) -> std::io::Result<()> {        use svg::node::element::Rectangle;        let x = 5.0;        let y = 10.0;        let rect = Rectangle::new()            .set("width", "100%")            .set("height", "100%")            .set("fill", "white");        let mut s = SierpinskiCurve::new(x, y, 7.0, 45);        let document = svg::Document::new()            .set("width", size)            .set("height", size)            .add(rect)            .add(s.execute(order));        svg::save(file, &document)    }} fn main() {    SierpinskiCurve::save("sierpinski_curve.svg", 545, 5).unwrap();}`
Output:

See: sierpinski_curve.svg (offsite SVG image)

## Sidef

Uses the LSystem() class from Hilbert curve.

`var rules = Hash(    x => 'xF+G+xF--F--xF+G+x',) var lsys = LSystem(    width:  550,    height: 550,     xoff: -9,    yoff: -271,     len:   5,    angle: 45,    color: 'dark green',) lsys.execute('F--xF--F--xF', 5, "sierpiński_curve.png", rules)`

Output image: Sierpiński curve

## Wren

Translation of: Go
Library: DOME
`import "graphics" for Canvas, Colorimport "dome" for Window var PX = 0var PY = 0var CX = 0var CY = 0var H  = 0 class SierpinskiCurve {    construct new(width, height, level, back, fore) {        Window.title = "Sierpinski Curve"        Window.resize(width, height)        Canvas.resize(width, height)        _w = width        _h = height        _l = level        _bc = back        _fc = fore    }     init() {        Canvas.cls(Color.blue)        CX = _w /2         CY = _h        H  = CX / 2.pow(_l + 1)        PX = CX - _w/2 + 2*H        PY = _h - CY + 3*H        squareCurve(_l)    }     lineTo(newX, newY) {        Canvas.line(PX, PY, PX = newX - _w/2 + H, PY = _h - newY + 2*H, _fc, 2)        CX = newX        CY = newY    }     lineN() { lineTo(CX, CY - 2*H) }    lineS() { lineTo(CX, CY + 2*H) }    lineE() { lineTo(CX + 2*H, CY) }    lineW() { lineTo(CX - 2*H, CY) }     lineNW() { lineTo(CX - H, CY - H) }    lineNE() { lineTo(CX + H, CY - H) }    lineSE() { lineTo(CX + H, CY + H) }    lineSW() { lineTo(CX - H, CY + H) }     sierN(level) {        if (level == 1) {            lineNE()            lineN()            lineNW()        } else {            sierN(level - 1)            lineNE()            sierE(level - 1)            lineN()            sierW(level - 1)            lineNW()            sierN(level - 1)        }    }     sierE(level) {        if (level == 1) {            lineSE()            lineE()            lineNE()        } else {            sierE(level - 1)            lineSE()            sierS(level - 1)            lineE()            sierN(level - 1)            lineNE()            sierE(level - 1)        }    }     sierS(level) {        if (level == 1) {            lineSW()            lineS()            lineSE()        } else {            sierS(level - 1)            lineSW()            sierW(level - 1)            lineS()            sierE(level - 1)            lineSE()            sierS(level - 1)        }    }     sierW(level) {        if (level == 1) {            lineNW()            lineW()            lineSW()        } else {            sierW(level - 1)            lineNW()            sierN(level - 1)            lineW()            sierS(level - 1)            lineSW()            sierW(level - 1)        }    }     squareCurve(level) {        sierN(level)        lineNE()        sierE(level)        lineSE()        sierS(level)        lineSW()        sierW(level)        lineNW()        lineNE() // needed to close the square in the top left hand corner    }     update() {}     draw(alpha) {}} var Game = SierpinskiCurve.new(770, 770, 5, Color.blue, Color.yellow)`

## zkl

Uses Image Magick and the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#zkl

`sierpinskiCurve(5) : turtle(_,45,45);	// n=5 --> 11,606 characters fcn sierpinskiCurve(order){   LSystem("F--XF--F--XF",Dictionary("X","XF+G+XF--F--XF+G+X"), order)}fcn LSystem(axiom,rules,order){   // Lindenmayer system    buf1,buf2 := Data(Void,axiom).howza(3), Data().howza(3);  // characters   do(order){      buf1.pump(buf2.clear(),'wrap(c){ rules.find(c,c) });   // change if rule      t:=buf1; buf1=buf2; buf2=t;	// swap buffers   }   buf1} fcn turtle(curve,angle,startAngle){  // angles in degrees   const D=10.0;   dir:=startAngle;   img,color := PPM(800,800), 0x00ff00;  // green on black   x,y := 15, img.h - x;   foreach c in (curve){      switch(c){	 case("F","G"){   // draw forward	    a,b := D.toRectangular(dir.toFloat().toRad());	    img.line(x,y, (x+=a.round()),(y+=b.round()), color) 	 }	 case("+"){ dir=(dir + angle)%360; } // turn left  angle	 case("-"){ dir=(dir - angle)%360; } // turn right angle      }   }   img.writeJPGFile("sierpinskiCurve.zkl.jpg");}`
Output:

Offsite image at Sierpinski curve order 5