Skip to content

Commit 39aaa86

Browse files
authored
Revamp dhall-lang.org (#1526)
The main changes are: * Rework the text substantially to match [the new "pitch"](https://discourse.dhall-lang.org/t/more-brainstorming-for-changing-the-dhall-lang-org-landing-page/101/18) * Add a new "Hash" tab to the live demo * Use the [new logo](dhall-lang/dhall-lang#803)
1 parent cc176e1 commit 39aaa86

File tree

6 files changed

+222
-64
lines changed

6 files changed

+222
-64
lines changed

dhall-try/completion.gif

133 KB
Loading

dhall-try/hash.gif

460 KB
Loading

dhall-try/index.html

Lines changed: 205 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<html>
33
<head>
44
<title>The Dhall configuration language</title>
5-
<meta name="description" content="A non-repetitive alternative to YAML">
5+
<meta name="description" content="Maintainable configuration files">
66
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
77
<meta name="viewport" content="width=device-width, initial-scale=1">
88
<style>
@@ -64,14 +64,14 @@
6464
</head>
6565
<body>
6666
<nav class="navbar sticky-top navbar-expand-lg navbar-light bg-light">
67-
<a class="navbar-left" href="https://dhall-lang.org"><img src="./img/dhall-large-logo.png" height="31px" alt="Dhall logo"></a>
67+
<a class="navbar-left" href="https://dhall-lang.org"><img src="./img/dhall-large-logo.svg" height="31px" alt="Dhall logo"></a>
6868
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
6969
<span class="navbar-toggler-icon"></span>
7070
</button>
7171

7272
<div class="collapse navbar-collapse" id="navbarSupportedContent">
7373
<ul class="navbar-nav ml-auto">
74-
<li class="nav-item mr-3 my-auto"><a href="https://github.com/dhall-lang/dhall-lang/wiki/Getting-started%3A-Generate-JSON-or-YAML" class="btn btn-primary">Get Started <i class="fas fa-running"></i></a></li>
74+
<li class="nav-item mr-3 my-auto"><a href="https://github.com/dhall-lang/dhall-lang/wiki/Getting-started%3A-Generate-JSON-or-YAML" class="btn btn-primary">Get started <i class="fas fa-running"></i></a></li>
7575
<li class="nav-item dropdown">
7676
<a class="nav-link dropdown-toggle" href="#" id="discussionDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
7777
Discussion
@@ -174,7 +174,7 @@
174174
</nav>
175175
<header>
176176
<h1 class="text-center">The Dhall configuration language</h1>
177-
<p class="lead text-center">The non-repetitive alternative to YAML</p>
177+
<p class="lead text-center">Maintainable configuration files</p>
178178
</header>
179179
<div class="container">
180180
<p class="lead text-center">
@@ -211,6 +211,9 @@ <h1 class="text-center">The Dhall configuration language</h1>
211211
<li class="nav-item">
212212
<a id="dhall-tab" class="nav-link mode-tab" href="#">Normalized</a>
213213
</li>
214+
<li class="nav-item">
215+
<a id="hash-tab" class="nav-link mode-tab" href="#">Hash</a>
216+
</li>
214217
<li class="nav-item">
215218
<a id="json-tab" class="nav-link mode-tab" href="#">JSON</a>
216219
</li>
@@ -222,50 +225,79 @@ <h1 class="text-center">The Dhall configuration language</h1>
222225
</div>
223226
</div>
224227
<div class="container jumbotron" style="background-color: #c5eccf">
225-
<h1 class="display-4">Human-friendly</h1>
226-
<p class="lead">Dhall supports comments, multi-line string literals and
227-
string interpolation with non-technical users in mind.</p>
228-
<textarea id="highlight0"></textarea>
229-
<p>You can also automatically remove all indirection in any Dhall code,
230-
converting the file to a logic-free normal form for non-programmers to
231-
understand.</p>
232-
<a href="https://github.com/dhall-lang/dhall-lang/wiki/Programmable-configuration-files"class="btn btn-lg btn-outline-dark bg-light">Learn More <i class="fas fa-book"></i></a>
228+
<h1 class="display-4">Don't repeat yourself</h1>
229+
<p class="lead">Struggling with configuration drift? Create a <a href="https://en.wikipedia.org/wiki/Single_source_of_truth">single source of truth</a> you can reference everywhere.</p>
230+
<hr class="my-4">
231+
<blockquote class="blockquote">
232+
<p>"Configuration drift occurs when a standardized group of IT resources, be they virtual servers, standard router configurations in VNF deployments, or any other deployment group that is built from a standard template, diverge in configuration over time. … The Infrastructure as Code methodology from DevOps is designed to combat Configuration Drift and other infrastructure management problems."</p>
233+
<footer class="blockquote-footer"><a href="https://kemptechnologies.com/glossary/configuration-drift/">Kemp Technologies on <cite title="Configuration Drift">Configuration Drift</cite></a></footer>
234+
<hr class="my-4">
235+
</blockquote>
236+
<p>Create a single authoritative configuration file:</p>
237+
<textarea rows="30" id="highlight0"></textarea>
238+
<p>… that you can read directly into several languages or convert to other file formats (including YAML or JSON).</p>
239+
<textarea rows="30" id="highlight1"></textarea>
240+
<a href="https://github.com/dhall-lang/dhall-lang/wiki/How-to-integrate-Dhall" class="btn btn-lg btn-outline-dark bg-light">Supported integrations <i class="fas fa-cogs" ></i></a>
241+
</div>
242+
<div class="container jumbotron" style="background-color: #cfebfb">
243+
<h1 class="display-4">Fearlessly refactor</h1>
244+
<p class="lead">Need to clean up a big mess? Move fast without breaking things by leaning on Dhall's tooling.</p>
245+
<hr class="my-4">
246+
<p>Refactoring something mission-critical? Use Dhall's support for
247+
semantic hashes to guarantee that a refactor is behavior-preserving</p>
248+
<img src="./img/hash.gif">
249+
<hr class="my-4">
250+
<p>What if you intend to make a change? Use a semantic diff to verify that
251+
you changed what you expected to:</p>
252+
<textarea id="diff"></textarea>
253+
<hr class="my-4">
254+
<p>Did you inherit a messy configuration? Use the type system and
255+
integrated editor support to navigate more effectively.</p>
256+
<img src="./img/completion.gif">
257+
<p></p>
258+
<a href="https://marketplace.visualstudio.com/items?itemName=panaeon.vscode-dhall-lsp-server" class="btn btn-lg btn-outline-dark bg-light">VSCode plugin <i class="fas fa-code" ></i></a>
233259
</div>
234260
<div class="container jumbotron" style="background-color: #fbecf1">
235-
<h1 class="display-4">Turing-completeness is not a feature</h1>
236-
<p class="lead">Dhall is programmable, but <b>NOT</b> Turing-complete.</p>
261+
<h1 class="display-4">Safety first</h1>
262+
<p class="lead">Sick of Turing-complete configuration languages? Dhall is
263+
a <a href="https://en.wikipedia.org/wiki/Total_functional_programming">
264+
total programming language</a> that forbids arbitrary side effects.</p>
237265
<hr class="my-4">
238266
<p>We take language security seriously so that your Dhall programs
239267
never fail, hang, crash, leak secrets, or compromise your system.</p>
240268
<p>The language aims to support safely importing and evaluating untrusted
241269
Dhall code, even code authored by malicious users. We treat the inability
242270
to do so as a specification bug.</p>
243-
<a href="https://github.com/dhall-lang/dhall-lang/wiki/Safety-guarantees"class="btn btn-lg btn-outline-dark bg-light">Safety Guarantees<i class="fas fa-shield-alt"></i></a>
244-
</div>
245-
<div class="container jumbotron" style="background-color: #cfebfb">
246-
<h1 class="display-4">Integration friendly</h1>
247-
<p class="lead">Dhall provides a smooth migration path for mature enterprise deployments.</p>
248-
<hr class="my-4">
249-
<p>You can convert both ways between Dhall and JSON/YAML or read Dhall
250-
configuration files directly into a language that supports a native
251-
language binding.</p>
252-
<a href="https://github.com/dhall-lang/dhall-lang/wiki/How-to-integrate-Dhall" class="btn btn-lg btn-outline-dark bg-light">Integrations <i class="fas fa-cogs" ></i></a>
271+
<a href="https://github.com/dhall-lang/dhall-lang/wiki/Safety-guarantees"class="btn btn-lg btn-outline-dark bg-light">Safety guarantees<i class="fas fa-shield-alt"></i></a>
253272
</div>
254273
<div class="container jumbotron" style="background-color: #fbf3c8">
255-
<h1 class="display-4">Tired of YAML?</h1>
256-
<p class="lead">Dhall eliminates the YAML quirks that software engineers
257-
dread. The language standard learns from the mistakes of the past.</p>
258-
<textarea id="highlight1"></textarea>
259-
<p>You can also generate either YAML or JSON from Dhall configuration
260-
files using tiny statically-linked binaries. Dhall can cheaply fit right
261-
in with your existing tools and infrastructure.</p>
262-
<a href="https://github.com/dhall-lang/dhall-lang/wiki/Getting-started%3A-Generate-JSON-or-YAML" class="btn btn-lg btn-outline-dark bg-light">Get Started <i class="fas fa-running"></i></a>
274+
<h1 class="display-4">Use programming language features</h1>
275+
<p class="lead">Hold your configuration files to the same standard of
276+
quality as the rest of your code.
277+
<hr class="my-4">
278+
<textarea id="highlight2"></textarea>
279+
<blockquote class="blockquote">
280+
<p>"Configuration bugs, not code bugs, are the most common cause I've seen of really bad outages. … As with error handling, I'm often told that it's obvious that config changes are scary, but it's not so obvious that most companies test and stage config changes like they do code changes."</p>
281+
<footer class="blockquote-footer"><a href="https://danluu.com/postmortem-lessons/">Dan Luu in <cite title="Reading postmortems">Reading postmortems</cite></a></footer>
282+
</blockquote>
283+
<div class="container">
284+
<div class="row">
285+
<div class="col-sm">
286+
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Configs are code are configs are code <a href="https://t.co/fVBs7T7P3j">https://t.co/fVBs7T7P3j</a></p>&mdash; Charity Majors (@mipsytipsy) <a href="https://twitter.com/mipsytipsy/status/1184673208491864064?ref_src=twsrc%5Etfw">October 17, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
287+
</div>
288+
<div class="col-sm">
289+
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Configuration testing is quite underrated in an industry where the majority of work is becoming configuration.</p>&mdash; JBD (@rakyll) <a href="https://twitter.com/rakyll/status/1177324158956388352?ref_src=twsrc%5Etfw">September 26, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
290+
</div>
291+
</div>
292+
</div>
293+
<a href="https://github.com/dhall-lang/dhall-lang/wiki/Getting-started%3A-Generate-JSON-or-YAML" class="btn btn-lg btn-outline-dark bg-light">Get started <i class="fas fa-running"></i></a>
263294
</div>
264295
<hr class="my-4">
265296
<p class="text-center">This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.</p>
266297
</body>
267298
<script language="javascript" src="./js/codemirror.js"></script>
268299
<script language="javascript" src="./js/haskell.js"></script>
300+
<script language="javascript" src="./js/shell.js"></script>
269301
<script language="javascript" src="./js/yaml.js"></script>
270302
<script language="javascript">
271303
let dhallInput = document.getElementById("dhall-input");
@@ -294,6 +326,22 @@ <h1 class="display-4">Tired of YAML?</h1>
294326
let highlight1 = document.getElementById("highlight1");
295327

296328
h1 = CodeMirror.fromTextArea(highlight1, {
329+
lineNumbers: true,
330+
mode: "shell",
331+
readOnly: true
332+
});
333+
334+
let diff = document.getElementById("diff");
335+
336+
d0 = CodeMirror.fromTextArea(diff, {
337+
lineNumbers: false,
338+
mode: "shell",
339+
readOnly: true
340+
});
341+
342+
let highlight2 = document.getElementById("highlight2");
343+
344+
h2 = CodeMirror.fromTextArea(highlight2, {
297345
lineNumbers: true,
298346
mode: "haskell",
299347
readOnly: true
@@ -308,6 +356,7 @@ <h1 class="display-4">Tired of YAML?</h1>
308356
let typeTab = document.getElementById("type-tab");
309357
let jsonTab = document.getElementById("json-tab");
310358
let yamlTab = document.getElementById("yaml-tab");
359+
let hashTab = document.getElementById("hash-tab");
311360

312361
function selectTab(tabClass, tabId) {
313362
Array.from(document.getElementsByClassName(tabClass)).forEach(element => {
@@ -320,7 +369,8 @@ <h1 class="display-4">Tired of YAML?</h1>
320369
321370
Can you spot the mistake?
322371
323-
Fix the typo, then move onto the "Definitions" example
372+
Fix the typo, then move onto the "Definitions"
373+
example
324374
-}
325375
326376
{ home = "/home/bill"
@@ -434,32 +484,130 @@ <h1 class="display-4">Tired of YAML?</h1>
434484

435485
input.setValue(example0);
436486

437-
h0.setValue(`let input =
438-
{ relative = "daughter"
439-
, movies = [ "Boss Baby", "Frozen", "Moana" ]
440-
}
487+
h0.setValue(`-- ./example.dhall
488+
489+
let Prelude =
490+
https://prelude.dhall-lang.org/v11.1.0/package.dhall sha256:99462c205117931c0919f155a6046aec140c70fb8876d208c7c77027ab19c2fa
491+
492+
let companyName = "Example Dot Com"
493+
494+
let User = { name : Text, account : Text, age : Natural }
495+
496+
let users
497+
: List User
498+
= [ { name = "John Doe", account = "john", age = 23 }
499+
, { name = "Jane Smith", account = "jane", age = 29 }
500+
, { name = "William Allen", account = "bill", age = 41 }
501+
]
502+
503+
let toEmail = \\(user : User) -> "\${user.account}@example.com"
504+
505+
let Bio = { name : Text, age : Natural }
506+
507+
let toBio = \\(user : User) -> user.(Bio)
508+
509+
let companySize = Prelude.List.length User users
510+
511+
let greetingPage =
512+
''
513+
<html>
514+
<title>Welcome to \${companyName}!</title>
515+
<body>
516+
<p>Welcome to our humble company of \${Natural/show companySize} people!</p>
517+
</body>
518+
</html>
519+
''
520+
521+
in { emails = Prelude.List.map User Text toEmail users
522+
, bios = Prelude.List.map User Bio toBio users
523+
, greetingPage = greetingPage
524+
}
525+
`);
441526

442-
let concatSep = https://prelude.dhall-lang.org/Text/concatSep
443-
444-
-- Dhall strips leading indentation for you
445-
in ''
446-
My \${input.relative} loves to watch \${concatSep ", " input.movies}
447-
448-
How about you?
449-
''`);
450-
451-
h1.setValue(`{ -- Unlike YAML, Dhall does not accept YES|NO|ON|OFF
452-
validDhallBools = [ True, False ]
453-
, someNumbers = [ 1
454-
,
455-
-- Dhall is not indentation-sensitive
456-
2, 3 ]
457-
-- Field names that conflict with reserved identifiers must be quoted
458-
, \`True\` = True
459-
, version = "9.3" {- Strings must be quoted
460-
461-
All Dhall literals have unambiguous types -}
527+
h1.setValue(`$ dhall-to-yaml <<< '(./company.dhall).bios'
528+
- age: 23
529+
name: John Doe
530+
- age: 29
531+
name: Jane Smith
532+
- age: 41
533+
name: William Allen
534+
535+
$ dhall-to-bash --declare EMAILS <<< '(./company.dhall).emails'
536+
declare -r -a EMAILS=(john@example.com jane@example.com bill@example.com)
537+
538+
$ dhall text <<< '(./company.dhall).greetingPage'
539+
<html>
540+
<title>Welcome to Example Dot Com!</title>
541+
<body>
542+
<p>Welcome to our humble company of 3 people!</p>
543+
</body>
544+
</html>
545+
`);
546+
547+
d0.setValue(`$ dhall diff \\
548+
'https://prelude.dhall-lang.org/v9.0.0/package.dhall' \\
549+
'https://prelude.dhall-lang.org/v10.0.0/package.dhall'
550+
{ Natural = { + equal = …
551+
, + greaterThan = …
552+
, + greaterThanEqual = …
553+
, + lessThan = …
554+
, + lessThanEqual = …
555+
, …
556+
}
557+
, Text = { + default = …
558+
, + defaultMap = …
559+
, …
560+
}
561+
, …
462562
}`);
563+
564+
h2.setValue(`-- Import packages
565+
let JSON = https://prelude.dhall-lang.org/v11.1.0/JSON/package.dhall
566+
567+
-- Use precise types like enums instead of strings
568+
let Zone = < us-east-1 | us-west-1 >
569+
570+
let InstanceType = < \`m5.large\` | \`m5.xlarge\` >
571+
572+
let Instance = { type : InstanceType, zone : Zone }
573+
574+
-- JSON rendering can optionally be implemented entirely within the language
575+
let Zone/toJSON =
576+
\\(zone : Zone)
577+
-> merge
578+
{ us-east-1 = JSON.string "us-east-1"
579+
, us-west-1 = JSON.string "us-west-1"
580+
}
581+
zone
582+
583+
let InstanceType/toJSON =
584+
\\(type : InstanceType)
585+
-> merge
586+
{ \`m5.large\` = JSON.string "m5.large"
587+
, \`m5.xlarge\` = JSON.string "m5.xlarge"
588+
}
589+
type
590+
591+
let Instance/toJSON =
592+
\\(instance : Instance)
593+
-> JSON.object
594+
( toMap
595+
{ type = InstanceType/toJSON instance.type
596+
, zone = Zone/toJSON instance.zone
597+
}
598+
)
599+
600+
-- Use language support for tests to safely verify code ahead of time
601+
let test =
602+
let example =
603+
{ type = InstanceType.\`m5.xlarge\`, zone = Zone.us-east-1 }
604+
605+
in assert
606+
: JSON.render (Instance/toJSON example)
607+
=== "{ \\"type\\": \\"m5.xlarge\\", \\"zone\\": \\"us-east-1\\" }"
608+
609+
in Instance/toJSON
610+
`);
463611
</script>
464612
<script defer language="javascript" src="./js/all.min.js"></script>
465613
</html>

dhall-try/src/Main.hs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ foreign import javascript unsafe "yamlTab.onclick = $1" registerYAMLOutput :: Ca
3838

3939
foreign import javascript unsafe "typeTab.onclick = $1" registerTypeOutput :: Callback (IO ()) -> IO ()
4040

41+
foreign import javascript unsafe "hashTab.onclick = $1" registerHashOutput :: Callback (IO ()) -> IO ()
42+
4143
foreign import javascript unsafe "output.setValue($1)" setOutput_ :: JSString -> IO ()
4244

4345
foreign import javascript unsafe "output.setOption('mode', $1)" setMode_ :: JSString -> IO ()
@@ -58,6 +60,7 @@ setMode Dhall = setMode_ "haskell"
5860
setMode Type = setMode_ "haskell"
5961
setMode JSON = setMode_ "javascript"
6062
setMode YAML = setMode_ "yaml"
63+
setMode Hash = setMode_ "null"
6164

6265
jsonConfig :: Data.Aeson.Encode.Pretty.Config
6366
jsonConfig =
@@ -72,7 +75,7 @@ jsonConfig =
7275
False
7376
}
7477

75-
data Mode = Dhall | Type | JSON | YAML deriving (Show)
78+
data Mode = Dhall | Type | JSON | YAML | Hash deriving (Show)
7679

7780
main :: IO ()
7881
main = do
@@ -140,6 +143,9 @@ main = do
140143
Right yamlText -> do
141144
setOutput yamlText
142145

146+
Hash -> do
147+
setOutput (Dhall.Import.hashExpressionToCode (Dhall.Core.alphaNormalize (Dhall.Core.normalize resolvedExpression)))
148+
143149
interpret
144150

145151
interpretAsync <- GHCJS.Foreign.Callback.asyncCallback interpret
@@ -164,3 +170,4 @@ main = do
164170
registerTabCallback Type "type-tab" registerTypeOutput
165171
registerTabCallback JSON "json-tab" registerJSONOutput
166172
registerTabCallback YAML "yaml-tab" registerYAMLOutput
173+
registerTabCallback Hash "hash-tab" registerHashOutput

0 commit comments

Comments
 (0)