Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Off-side rule
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
{{Short description|Programming language syntax rule that defines code block demarcation via indentation}} {{About|the programming language syntax feature||Offside (disambiguation)}} {{Refimprove|date=December 2011}} {{Use mdy dates|date=July 2022}} The '''off-side rule''' describes [[Syntax (programming languages)|syntax]] of a [[computer]] [[programming language]] that defines the bounds of a [[block (programming)|code block]] via [[indent style|indentation]].<ref> {{cite conference | first= G. | last= Hutton | editor-first= Kei | editor-last= Davis | editor2-first= John | editor2-last= Hughes | title= Parsing Using Combinators | book-title= Functional Programming: Proceedings of the 1989 Glasgow Workshop 21β23 August 1989, Fraserburgh, Scotland | pages= 362β364 | publisher= Springer Science & Business Media | date= Dec 6, 2012 | isbn= 9781447131663 | url= https://books.google.com/books?id=GiLjBwAAQBAJ&dq=offside+rule+programming&pg=PA363 | access-date= September 3, 2015}} </ref><ref> {{cite conference | first= D.A. | last= Turner | editor-first= Hans Wolfgang | editor-last= Loidl | editor2-first= Ricardo | editor2-last= PeΓ±a | title= Some History of Functional Programming Languages (Invited Talk) | book-title= Trends in Functional Programming: 13th International Symposium, TFP 2012, St Andrews, UK, June 12β14, 2012, Revised Selected Papers | pages= 8 | publisher= Springer | date= August 13, 2013 | isbn= 9783642404474 | url= https://books.google.com/books?id=B_25BQAAQBAJ&dq=Offside+rule+programming&pg=PA8 | access-date= September 3, 2015}}</ref> The term was coined by [[Peter Landin]], possibly as a pun on the [[Offside (association football)|offside law]] in [[association football]]. An off-side rule language is contrasted with a [[free-form language]] in which indentation has no syntactic meaning, and indentation is strictly a matter of [[Programming style|style]]. An off-side rule language is also described as having '''significant indentation'''. == Definition == [[Peter Landin]], in his 1966 article "[[The Next 700 Programming Languages]]", defined the off-side rule thus: "Any non-whitespace token to the left of the first such token on the previous line is taken to be the start of a new declaration."<ref>{{cite journal |last1=Landin |first1=P. J. |author1-link=Peter Landin |date=March 1966 |title=The next 700 programming languages |doi=10.1145/365230.365257 |journal=[[Communications of the ACM]] |volume=9 |issue=3 |pages=157β166 |s2cid=13409665 |url=http://fsl.cs.uiuc.edu/images/e/ef/P157-landin.pdf}}</ref> == Example == The following is an example of indentation blocks in [[Python (programming language)|Python]]; a popular off-side rule language. In Python, the rule is taken to define the boundaries of statements rather than declarations. <syntaxhighlight lang="python" line> def is_even(a: int) -> bool: if a % 2 == 0: print('Even!') return True print('Odd!') return False </syntaxhighlight> The body of the function starts on line 2 since it is indented one level (4 spaces) more than the previous line. The <code>if</code> clause body starts on line 3 since it is indented an additional level, and ends on line 4 since line 5 is indented a level less, a.k.a. outdented. The colon (<code>:</code>) at the end of a control statement line is Python syntax; not an aspect of the off-side rule. The rule can be realized without such colon syntax. ==Implementation== The off-side rule can be implemented in the [[lexical analysis]] phase, as in [[Python (programming language)|Python]], where increasing the indenting results in the lexer outputting an <code>INDENT</code> token, and decreasing the indenting results in the lexer outputting a <code>DEDENT</code> token.<ref>[https://docs.python.org/ Python Documentation], [https://docs.python.org/3/reference/lexical_analysis.html 2. Lexical analysis]: [https://docs.python.org/3/reference/lexical_analysis.html#indentation 2.1.8. Indentation]</ref> These tokens correspond to the opening brace <code>{</code> and closing brace <code>}</code> in languages that use braces for blocks, and means that the phrase grammar does not depend on whether braces or indentation are used. This requires that the lexer hold state, namely the current indent level, and thus can detect changes in indentation when this changes, and thus the lexical [[Formal grammar|grammar]] is not [[Context-free grammar|context-free]]: <code>INDENT</code> and <code>DEDENT</code> depend on the contextual information of the prior indent level. ==Alternatives== The primary alternative to delimiting blocks by indenting, popularized by broad use and influence of the language [[C (programming language)|C]], is to ignore [[whitespace character]]s and mark blocks explicitly with [[curly bracket]]s (i.e., <code>{</code> and <code>}</code>) or some other delimiter. While this allows for more formatting freedom β a developer might choose not to indent small pieces of code like the [[Control flow#Continuation with next iteration|break and continue statements]] β sloppily indented code might lead the reader astray, such as the [[goto fail]] bug. [[Lisp (programming language)|Lisp]] and other [[S-expression]]-based languages do not differentiate statements from expressions, and parentheses are enough to control the scoping of all statements within the language. As in curly bracket languages, whitespace is mostly ignored by the reader (i.e., the read function). Whitespace is used to separate tokens.<ref>{{Cite web|url=http://clhs.lisp.se/Body/02_adg.htm|title = CLHS: Section 2.1.4.7}}</ref> The explicit structure of Lisp code allows automatic indenting, to form a visual cue for human readers. Another alternative is for each block to begin and end with explicit keywords. For example, in [[ALGOL 60]] and its descendant [[Pascal (programming language)|Pascal]], blocks start with [[Reserved word|keyword]] <code>begin</code> and end with keyword <code>end</code>. In some languages (but not Pascal), this means that newlines ''are'' important{{citation needed|date=June 2012}} (unlike in curly brace languages), but the indentation is not. In [[BASIC]] and [[Fortran]], blocks begin with the block name (such as <code>IF</code>) and end with the block name prepended with <code>END</code> (e.g., <code>END IF</code>). In [[Fortran]], each and every block can also have its own unique block name, which adds another level of explicitness to lengthy code. [[ALGOL 68]] and the [[Bourne shell]] (sh, and [[Bash (Unix shell)|bash]]) are similar, but the end of the block is usually given by the name of the block written backward (e.g., <code>case</code> starts a [[switch statement]] and it spans until the matching <code>esac</code>; similarly [[conditional (computer programming)|conditionals]] <code>if</code>...<code>then</code>...[<code>elif</code>...[<code>else</code>...]]<code>fi</code> or [[for loop|''for'' loops]] <code>for</code>...<code>do</code>...<code>od</code> in ALGOL68 or <code>for</code>...<code>do</code>...<code>done</code> in bash). An interesting variant of this occurs in [[Modula-2]], a Pascal-like language which does away with the difference between one and multiline blocks. This allows the block opener (<code>{</code> or <code>BEGIN</code>) to be skipped for all but the function level block, requiring only a block terminating token (<code>}</code> or <code>END</code>). It also fixes [[dangling else]]. Custom is for the <code>end</code> token to be placed on the same indent level as the rest of the block, giving a blockstructure that is very readable. One advantage to the [[Fortran]] approach is that it improves readability of long, nested, or otherwise complex code. A group of outdents or closing brackets alone provides no contextual cues as to which blocks are being closed, necessitating backtracking, and closer scrutiny while [[debugging]]. Further, languages that allow a suffix for END-like keywords further improve such cues, such as <code>continue</code> versus <code>continue for x</code>, and [[For loop#1964: BASIC | end-loop marker specifying the index variable]] <code>NEXT I</code> versus <code>NEXT</code>, and [[For loop#Early exit and continuation | uniquely named loops]] <code>CYCLE X1</code> versus <code>CYCLE</code>. However, modern [[source code editor]]s often provide visual indicators, such as [[syntax highlighting]], and features such as [[code folding]] to assist with these drawbacks. ==Productivity== In the language [[Scala (programming language)|Scala]], early versions allowed curly braces only. Scala 3 added an option to use indenting to structure blocks. Designer Martin Odersky said that this was the single most important way Scala 3 improved his own productivity, that it makes programs over 10% shorter and keeps programmers "in the flow", and advises its use.<ref>{{Cite AV media |last=Odersky |first=Martin |date=17 June 2020 |title=Martin Odersky: A Scala 3 Update |medium=video |language=en |url=https://www.youtube.com/watch?v=Z0w_pITUTyU |archive-url=https://ghostarchive.org/varchive/youtube/20211221/Z0w_pITUTyU |archive-date=2021-12-21 |url-status=live|time=36:35β45:08 |publisher=YouTube |access-date=2021-04-25}}{{cbignore}}</ref> == Notable programming languages == Notable programming languages with the off-side rule: * [[ABC (programming language)|ABC]] * [[Agda (programming language)|Agda]] * [[Boo (programming language)|Boo]] * [[Cobra (programming language)|Cobra]] * [[CoffeeScript]] * Converge * [[Curry (programming language)|Curry]] * [[Elm (programming language)|Elm]] * [[F Sharp (programming language)|F#]], in early versions, when <code>#light</code> is specified; in later versions when <code>#light "off"</code> is not<ref>{{Cite web |url=https://blogs.msdn.microsoft.com/dsyme/2009/05/20/detailed-release-notes-for-the-f-may-2009-ctp-update-and-visual-studio-2010-beta1-releases/ |title=Detailed Release Notes for the F# May 2009 CTP Update and Visual Studio 2010 Beta1 releases |last1=Syme |first1=Don |date=May 20, 2009 |archive-url=https://web.archive.org/web/20190121121601/https://blogs.msdn.microsoft.com/dsyme/2009/05/20/detailed-release-notes-for-the-f-may-2009-ctp-update-and-visual-studio-2010-beta1-releases/ |archive-date=2019-01-21}}</ref> * [[Godot (game engine)#GDScript|GDScript (Godot engine)]] * [[Haskell]],<ref>[http://haskell.org/onlinereport/lexemes.html#sect2.7 The Haskell Report β Layout]</ref> only for <code>where</code>, <code>let</code>, <code>do</code>, or <code>case ... of</code> clauses when braces are omitted * [[Inform 7]] * [[ISWIM]], the abstract language that introduced the rule * [[LiveScript (programming language)|LiveScript]] * Lobster<ref>[https://strlen.com/lobster Lobster, a programming language with static typing and compile-time memory management for game/graphical development]</ref> * [[Miranda (programming language)|Miranda]] * MoonScript<ref>[https://moonscript.org MoonScript, a language that compiles to Lua]</ref><ref>[https://moonscript.org/reference/#the-language/whitespace MoonScript 0.5.0 β Language Guide]</ref> * [[Nemerle]], optional mode * [[Nim (programming language)|Nim]] * [[occam (programming language)|occam]] <!--occam isn't written with upper case--> * [[PROMAL]] * [[Python (programming language)|Python]] * [[Scala (programming language)|Scala]], optional mode * [[Scheme (programming language)|Scheme]], when using one of several [[Scheme Requests for Implementation]]s, the latest of which is [http://srfi.schemers.org/srfi-119/srfi-119.html SRFI 119] * [[Spin (programming language)|Spin]] * Woma * [[XL (programming language)|XL]] == Other file formats == Notable non-programming language, text file formats with significant indentation: * [[GCode]], RepRapFirmware dialect <ref>{{cite web |url=https://docs.duet3d.com/User_manual/Reference/Gcode_meta_commands |title=GCode meta commands}}</ref> * [[Haml]] * [[Make (software)|Make]], tab-indented line signifies a command * Pug (formerly Jade), see [[Comparison of web template engines]] * [[reStructuredText]]<ref>[http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#id38 reStructuredText Markup Specification β Indentation]</ref> * [[Sass (stylesheet language)|Sass]] * [[Stylus (stylesheet language)|Stylus]] * [[YAML]] ==See also== *{{Format link|Python syntax and semantics#Indentation}} *[[Prettyprint]] ==References== {{Reflist}} {{Types of programming languages}} [[Category:Programming language topics]] <!-- Hidden categories below --> [[Category:Articles with example Python (programming language) code]]
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)
Pages transcluded onto the current version of this page
(
help
)
:
Template:About
(
edit
)
Template:Cbignore
(
edit
)
Template:Citation needed
(
edit
)
Template:Cite AV media
(
edit
)
Template:Cite conference
(
edit
)
Template:Cite journal
(
edit
)
Template:Cite web
(
edit
)
Template:Format link
(
edit
)
Template:Refimprove
(
edit
)
Template:Reflist
(
edit
)
Template:Short description
(
edit
)
Template:Types of programming languages
(
edit
)
Template:Use mdy dates
(
edit
)