773 words
~4min read

What language am I writing again?

March 23rd 2022
2K views

Have you ever had that brainfart moment when you’re writing code and forget what syntax you’re supposed to be using? An example is helpful:

/** ...imports... */

export const AccountQuery = gql`
  query exampleQuery($id: ID!) {
    account(id: $id) {
      id
      name
      addresses(type: [BUSINESS]) {
        id
        street
        street2
        city
        state
        type
      }
      parentAccount {
        id
      }
    }
  }
`;

const StyledWrapper = styled.div`
  margin: 10px auto;
  background-color: ${palettes.gray[700]};
`;
const AddressDisplay = styled.div`
  text-align: left;
`;

export const GrowerTINEditContainer = () => {
  const { accountId } = useParams<{ accountId: string }>();

  const { data, error, loading } = useQuery<ExampleQueryData, ExampleQueryVariables>(AccountQuery, {
    variables: { id: accountId },
  });

  if (loading) { return <Loader />; }

  if (error || !data?.account) {
    throw new Error('Could not retrieve account');
  }

  return (
    <StyledWrapper>
      <SubComponent account={data?.account} />

      {data?.account.addresses.map(address =>
        <AddressDisplay
          key={address.id}
          address={address}
        >
          {`${address.street} ${address.city}, ${address.state}`}
        </AddressDisplay>
      )}
    </StyledWrapper>
  );
};

This is from a recent project that used React + Typescript + GraphQL + Styled Components which is a prime combo for this sort of situation. At bare minimum we have these languages all represented in the same file.

  • Typescript
  • GraphQL
  • CSS
  • React

Depending on how you’re counting, you could also add in Javascript (since you need to know it anyways for Typescript), HTML (since the React syntax is built on it), and even the interpolated strings like ${address.street} ${address.city}, ${address.state} which have a special syntax on their own.

This isn’t particularly a new trend. Perhaps you’ve had the ‘fortune?’ in your career to remember code like this that used to be a norm.


<?php session_start(); ?>
<script>
    if (window.history.replaceState) { window.history.replaceState(null, null, window.location.href); }
</script>

<?php

header('Cache-control: no-cache, must-revalidate, max-age=0');
require('../mediaasset/db.php');
$_SESSION['prmshow'] = "display: none";

if (isset($_POST['upprm'])) {

    $sqlprm = "SELECT * FROM program WHERE prmid = '$prmid'";
    $resultprm = mysqli_query($db, $sqlprm) or die(mysqli_error($db));
    $countprm = mysqli_num_rows($resultprm);
    $rowprm = mysqli_fetch_array($resultprm);

    if ($countprm = 1) {
        // Insert Data
        $inputprm = "UPDATE program SET pname='$_POST[pname]', ptime='$_POST[ptime]', pday='$_POST[pday]', prj1='$_POST[prj1]', prj2='$_POST[prj2]', pgraphic='$_POST[pgraphic]', ptelecast='$_POST[ptelecast]', pserial='$_POST[pserial]' WHERE prmid='$prmid'";

        if (mysqli_query($db, $inputprm)) {
            echo "<script type='text/javascript'> document.location = 'program.php?program=$prmid'; </script>";
            exit;
        }
    }
}

?>

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="style.css">
</head>

<body>
  <div style="max-width: 200px;width: 100%;float:right;margin-top: -3px;">
    <form action="" method="get">
      <select name="program" style="width: 350px;" onchange="javascript:this.form.submit()">
          <option value="0" hidden>Programme List</option>
          <?php
          $sqlprmslt = "SELECT * FROM program ORDER BY id ASC";
          $resultprmslt = mysqli_query($db, $sqlprmslt);
          while ($rowprmslt = mysqli_fetch_array($resultprmslt, MYSQLI_ASSOC)) {
          ?>
              <option value="<?php echo $rowprmslt['prmid'] ?>"><?php echo $rowprmslt['pname'] ?></option>
          <?php
          }
          ?>
      </select>
    </form>
  </div>
</body>
</html>

I found this example on GitHub and stripped it down a lot for brevity and sanities sake, but even still it gives me flashbacks of seeing 4000 line PHP files that mix and match PHP, SQL, HTML, Javascript, and CSS all in one big convoluted mess.

You might be asking yourself “ok there’s a lot of languages, is that always bad though?”. One thought experiment I like to test ideas against is taking them to the extreme and see where it goes. For this example, the extremes are:

  • The file only has one language
  • The file has 10 (20?, 30?, 100?) different languages in it. You switch between them practically on a character by character basis.

Straight away I know which extreme I want to aim towards. I’m pragmatist so I’m not saying that files must only ever contain a single language, but the exercise gets you thinking about the ideal and where the breaking point is.

There’s some notable disadvantages of having many languages in a file, and particularly embedding languages within other languages like the GQL and CSS inside the strings in the first example.

  1. More cognitive overhead
  2. Editor tooling is harder and slower
  3. Single responsibility principle suffers heavily

There have been some interesting experiments with composing languages together at runtime. I agree with the author’s plight that switching languages is all too hard and we end up getting locked into our choices, however I don’t agree that their solution of composing languages together as they did is the right one. As mentioned in the conclusion, there’s a lot of friction switching languages. A lot of weird edge cases. A lot of, for lack of a better term, “magic”. Well, maybe there is a better term: complexity. Since our prime directive as software engineers is to manage complexity and keep it at a minimum we have to keep looking for other solutions.

As mentioned before, I’m not about to go preaching to the world that you should only have one language per file, just that your eyebrows should instinctively move up when you see this happening. Design is all about balancing trade-offs, and this is no exception.

Have you’ve seen some egregious examples in your career? Perhaps a bunch of DSL’s mixed in? Share them in the comments!

Want the inside scoop?

Sign up and be the first to see new posts

No spam, just the inside scoop and $10 off any photo print!